Experian_Data_Quality_Validation_Services - Version 1.0.0.0

Version Notes

Address verification for both front and back-end touch points, with support for addresses in the USA, CAN, GBR, IRE, and DEU.

Email and phone verification services provide real-time verification at the point of entry.

This extension is a bundle containing Experian Data Quality's address and email/phone products in a single extension. Separate license keys may be necessary for each service. Contact your Experian Data Quality sales representative for more information.

Download this release

Release Info

Developer David Morton
Extension Experian_Data_Quality_Validation_Services
Version 1.0.0.0
Comparing to
See all releases


Version 1.0.0.0

Files changed (117) hide show
  1. app/code/community/EDQ/AddressValidation/Helper/Data.php +4 -0
  2. app/code/community/EDQ/AddressValidation/Helper/Methods.php +102 -0
  3. app/code/community/EDQ/AddressValidation/Helper/Settings.php +164 -0
  4. app/code/community/EDQ/AddressValidation/Model/Customer.php +21 -0
  5. app/code/community/EDQ/AddressValidation/Model/DataCenters.php +29 -0
  6. app/code/community/EDQ/AddressValidation/Model/DoCanSearchParameters.php +13 -0
  7. app/code/community/EDQ/AddressValidation/Model/Observer.php +74 -0
  8. app/code/community/EDQ/AddressValidation/Model/Quote.php +21 -0
  9. app/code/community/EDQ/AddressValidation/Model/Resource/Customer.php +8 -0
  10. app/code/community/EDQ/AddressValidation/Model/Resource/Customer/Collection.php +8 -0
  11. app/code/community/EDQ/AddressValidation/Model/Resource/Quote.php +8 -0
  12. app/code/community/EDQ/AddressValidation/Model/Resource/Quote/Collection.php +8 -0
  13. app/code/community/EDQ/AddressValidation/Model/Service.php +406 -0
  14. app/code/community/EDQ/AddressValidation/Model/ServiceProviders.php +27 -0
  15. app/code/community/EDQ/AddressValidation/Model/Validate.php +195 -0
  16. app/code/community/EDQ/AddressValidation/controllers/ProcessAdminController.php +173 -0
  17. app/code/community/EDQ/AddressValidation/controllers/ProcessController.php +409 -0
  18. app/code/community/EDQ/AddressValidation/etc/adminhtml.xml +22 -0
  19. app/code/community/EDQ/AddressValidation/etc/config.xml +149 -0
  20. app/code/community/EDQ/AddressValidation/etc/system.xml +356 -0
  21. app/code/community/EDQ/AddressValidation/sql/addressvalidation_setup/install-1.0.5.php +91 -0
  22. app/code/community/EDQ/EmailAndPhoneValidation/Helper/Data.php +208 -0
  23. app/code/community/EDQ/EmailAndPhoneValidation/Model/Observer.php +27 -0
  24. app/code/community/EDQ/EmailAndPhoneValidation/Model/Phone/PhoneFormater.php +173 -0
  25. app/code/community/EDQ/EmailAndPhoneValidation/Model/SupportedCountries.php +20 -0
  26. app/code/community/EDQ/EmailAndPhoneValidation/Model/System/Config/Source/Countries.php +18 -0
  27. app/code/community/EDQ/EmailAndPhoneValidation/Model/Validate.php +187 -0
  28. app/code/community/EDQ/EmailAndPhoneValidation/controllers/ValidationController.php +141 -0
  29. app/code/community/EDQ/EmailAndPhoneValidation/etc/adminhtml.xml +23 -0
  30. app/code/community/EDQ/EmailAndPhoneValidation/etc/config.xml +75 -0
  31. app/code/community/EDQ/EmailAndPhoneValidation/etc/system.xml +113 -0
  32. app/design/adminhtml/default/default/layout/edqaddressvalidation.xml +21 -0
  33. app/design/adminhtml/default/default/layout/edqemailandphonevalidation.xml +14 -0
  34. app/design/adminhtml/default/default/template/edq/initialize.phtml +186 -0
  35. app/design/adminhtml/default/default/template/edq/singleline.phtml +181 -0
  36. app/design/adminhtml/default/default/template/edq/verify.phtml +210 -0
  37. app/design/frontend/base/default/layout/edqaddressvalidation.xml +123 -0
  38. app/design/frontend/base/default/layout/edqemailandphonevalidation.xml +66 -0
  39. app/design/frontend/base/default/template/edq/checkout/configurations.phtml +54 -0
  40. app/design/frontend/base/default/template/edq/checkout/verify.phtml +407 -0
  41. app/design/frontend/base/default/template/edq/customer/address/phoneConfigurations.phtml +31 -0
  42. app/design/frontend/base/default/template/edq/customer/form/emailConfigurations.phtml +29 -0
  43. app/design/frontend/base/default/template/edq/customer/verify.phtml +351 -0
  44. app/design/frontend/base/default/template/edq/initialize.phtml +124 -0
  45. app/design/frontend/base/default/template/edq/interaction.phtml +178 -0
  46. app/design/frontend/base/default/template/edq/popup.phtml +50 -0
  47. app/design/frontend/base/default/template/edq/rightside.phtml +89 -0
  48. app/design/frontend/base/default/template/edq/securityToken.phtml +40 -0
  49. app/design/frontend/base/default/template/edq/singleline.phtml +182 -0
  50. lib/EDQ/WshEmailValidator.php +12 -0
  51. lib/EDQ/WshPhoneValidator.php +12 -0
  52. lib/EDQ/WshValidator.php +136 -0
  53. lib/EDQ/WshValidatorFactory.php +19 -0
  54. lib/ExperianDataQuality/Address.php +14 -0
  55. lib/ExperianDataQuality/AddressLine.php +20 -0
  56. lib/ExperianDataQuality/AddressValidationParser.php +127 -0
  57. lib/ExperianDataQuality/AddressValidationReference.php +432 -0
  58. lib/ExperianDataQuality/BaseService.php +165 -0
  59. lib/ExperianDataQuality/Common/GlobalSettings.php +148 -0
  60. lib/ExperianDataQuality/Common/HelperMethods.php +29 -0
  61. lib/ExperianDataQuality/Common/Request/BaseAddressRequest.php +42 -0
  62. lib/ExperianDataQuality/Common/Request/BaseSearchRequest.php +69 -0
  63. lib/ExperianDataQuality/Common/Request/CanSearchRequest.php +10 -0
  64. lib/ExperianDataQuality/Common/Request/GetAddressRequest.php +7 -0
  65. lib/ExperianDataQuality/Common/Request/GetLayoutsRequest.php +31 -0
  66. lib/ExperianDataQuality/Common/Request/RefineRequest.php +9 -0
  67. lib/ExperianDataQuality/Common/Request/SearchRequest.php +56 -0
  68. lib/ExperianDataQuality/Common/Response/BaseSearchResponse.php +24 -0
  69. lib/ExperianDataQuality/Common/Response/CanSearchResponse.php +17 -0
  70. lib/ExperianDataQuality/Common/Response/GetAddressResponse.php +13 -0
  71. lib/ExperianDataQuality/Common/Response/GetLayoutResponse.php +7 -0
  72. lib/ExperianDataQuality/Common/Response/RefineResponse.php +7 -0
  73. lib/ExperianDataQuality/Common/Response/SearchResponse.php +7 -0
  74. lib/ExperianDataQuality/DPVStatusType.php +11 -0
  75. lib/ExperianDataQuality/EngineEnumType.php +9 -0
  76. lib/ExperianDataQuality/EngineType.php +44 -0
  77. lib/ExperianDataQuality/IService.php +20 -0
  78. lib/ExperianDataQuality/Layout.php +12 -0
  79. lib/ExperianDataQuality/LineContentType.php +9 -0
  80. lib/ExperianDataQuality/Picklist.php +12 -0
  81. lib/ExperianDataQuality/PicklistEntry.php +36 -0
  82. lib/ExperianDataQuality/ProOnDemandService.php +63 -0
  83. lib/ExperianDataQuality/ProOnDemandService.wsdl +1081 -0
  84. lib/ExperianDataQuality/PromptSetType.php +11 -0
  85. lib/ExperianDataQuality/QAAddress.php +41 -0
  86. lib/ExperianDataQuality/QAAuthentication.php +12 -0
  87. lib/ExperianDataQuality/QACanSearch.php +16 -0
  88. lib/ExperianDataQuality/QAGetAddress.php +13 -0
  89. lib/ExperianDataQuality/QAGetLayouts.php +10 -0
  90. lib/ExperianDataQuality/QALayouts.php +29 -0
  91. lib/ExperianDataQuality/QAPicklist.php +45 -0
  92. lib/ExperianDataQuality/QAQueryHeader.php +14 -0
  93. lib/ExperianDataQuality/QARefine.php +20 -0
  94. lib/ExperianDataQuality/QASearch.php +25 -0
  95. lib/ExperianDataQuality/QASearchOk.php +16 -0
  96. lib/ExperianDataQuality/QASearchResult.php +19 -0
  97. lib/ExperianDataQuality/ServiceFactory.php +29 -0
  98. lib/ExperianDataQuality/VerifyLevelType.php +12 -0
  99. package.xml +22 -0
  100. skin/adminhtml/default/default/ExperianDataQuality/images/opc-ajax-loader.gif +0 -0
  101. skin/adminhtml/default/default/ExperianDataQuality/js/edqAddressClient.js +672 -0
  102. skin/adminhtml/default/default/ExperianDataQuality/js/edqClient.js +565 -0
  103. skin/adminhtml/default/default/ExperianDataQuality/js/json2.js +480 -0
  104. skin/adminhtml/default/default/ExperianDataQuality/js/system.js +119 -0
  105. skin/adminhtml/default/default/edq/images/opc-ajax-loader.gif +0 -0
  106. skin/adminhtml/default/default/edq/js/edqClient.js +526 -0
  107. skin/adminhtml/default/default/edq/js/json2.js +480 -0
  108. skin/adminhtml/default/default/edq/js/system.js +46 -0
  109. skin/frontend/base/default/ExperianDataQuality/images/opc-ajax-loader.gif +0 -0
  110. skin/frontend/base/default/ExperianDataQuality/js/edqAddressClient.js +611 -0
  111. skin/frontend/base/default/ExperianDataQuality/js/edqClient.js +575 -0
  112. skin/frontend/base/default/ExperianDataQuality/js/json2.js +480 -0
  113. skin/frontend/base/default/ExperianDataQuality/js/system.js +119 -0
  114. skin/frontend/base/default/edq/images/opc-ajax-loader.gif +0 -0
  115. skin/frontend/base/default/edq/js/edqClient.js +526 -0
  116. skin/frontend/base/default/edq/js/json2.js +480 -0
  117. skin/frontend/base/default/edq/js/system.js +46 -0
app/code/community/EDQ/AddressValidation/Helper/Data.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Helper_Data extends Mage_Core_Helper_Abstract {
3
+
4
+ }
app/code/community/EDQ/AddressValidation/Helper/Methods.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php');
3
+
4
+ class EDQ_AddressValidation_Helper_Methods extends Mage_Core_Helper_Abstract
5
+ {
6
+ public function getValueOrEmptyString($key, $array)
7
+ {
8
+ return array_key_exists($key, $array) ? $array[$key] : '';
9
+ }
10
+
11
+ public function getRegisteredAddress($customerAddressId, $sizeOfStreet)
12
+ {
13
+ $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
14
+ $returnAddress = array();
15
+
16
+ if ($customerAddress->getId())
17
+ {
18
+ $returnAddress['street'] = $customerAddress->getStreet();
19
+
20
+ while(count($returnAddress['street']) < $sizeOfStreet)
21
+ {
22
+ $returnAddress['street'][]='';
23
+ }
24
+ $returnAddress['city'] = $customerAddress->getCity();
25
+ $returnAddress['region_id'] = $customerAddress->getRegion_id();
26
+ $returnAddress['postcode'] = $customerAddress->getPostcode();
27
+ $returnAddress['country_id'] = $customerAddress->getCountry_id();
28
+ }
29
+
30
+ return $returnAddress;
31
+ }
32
+
33
+ public function createSearchRequest($data)
34
+ {
35
+ $searchRequest = new SearchRequest();
36
+ $searchRequest->Street1 = $data['address']['street'][0];
37
+ $searchRequest->Street2 = $data['address']['street'][1];
38
+ $searchRequest->City = $data['address']['city'];
39
+ $searchRequest->State = $this->_getService()->getRegion($data['address']['region_id']);
40
+ $searchRequest->Postcode = $data['address']['postcode'];
41
+ $searchRequest->DataSet = $data['address']['country_id'];
42
+
43
+ return $searchRequest;
44
+ }
45
+
46
+ public function createEdqInfo($searchResult, &$data)
47
+ {
48
+ $edqInfo = array();
49
+
50
+ if($searchResult != null && array_key_exists('matchType', $searchResult) && $searchResult['matchType'] !== 'error')
51
+ {
52
+ $edqInfo['matchType'] = $searchResult['matchType'];
53
+
54
+ if(isset($searchResult['cleanAddress']) && count($searchResult['cleanAddress']) < count($data['address']['street']) + 3)
55
+ {
56
+ $edqInfo['matchType'] = 'error';
57
+ $edqInfo['error'] = $this->_getTranslation(
58
+ 'Invalid Layout. Make sure your layout conforms
59
+ to having as many street address lines as
60
+ your magento setup followed by three lines
61
+ containing City, State, Zip.');
62
+ }
63
+ else
64
+ {
65
+ $key = 'Line';
66
+ for($i = 0; $i < count($data['address']['street']); $i++)
67
+ {
68
+ $data['address']['street'][$i] = $searchResult['cleanAddress'][$key . $i];
69
+ }
70
+ $data['address']['city'] = $searchResult['cleanAddress'][$key . $i];
71
+ $data['address']['region_id'] = $searchResult['cleanAddress'][$key . ($i + 1)];
72
+ $data['address']['postcode'] = $searchResult['cleanAddress'][$key . ($i + 2)];
73
+ $edqInfo['additionalData'] = '';
74
+ for($j = $i + 3; $j < count($searchResult['cleanAddress']); $j++)
75
+ {
76
+ $edqInfo['additionalData'] .= $searchResult['cleanAddress'][$key . $j] . '|';
77
+ }
78
+ }
79
+ }
80
+ else if($searchResult['matchType'])
81
+ {
82
+ $edqInfo['matchType'] = 'error';
83
+ $edqInfo['error'] = $searchResult['error'];
84
+ }
85
+ else
86
+ {
87
+ $edqInfo['matchType'] = 'bypass';
88
+ }
89
+
90
+ return $edqInfo;
91
+ }
92
+
93
+ private function _getService()
94
+ {
95
+ return Mage::getModel('addressvalidation/Service');
96
+ }
97
+
98
+ private function _getTranslation($text)
99
+ {
100
+ return Mage::getSingleton('core/translate')->translate(array($text));
101
+ }
102
+ }
app/code/community/EDQ/AddressValidation/Helper/Settings.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Helper_Settings extends Mage_Core_Helper_Abstract
3
+ {
4
+ const XML_PATH_TO_SETTINGS = 'experiandataquality_addressvalidation/settings/';
5
+ const XML_KEY_SERVICE = 'service_type';
6
+ const XML_KEY_ENDPOINT = 'endpoint';
7
+ const XML_KEY_TOKEN = 'token';
8
+ const XML_KEY_USER_INTERACTION = 'user_interaction';
9
+ const XML_KEY_USA_CLEAN = 'usa_clean';
10
+ const XML_KEY_USA_LAYOUT = 'usa_layout';
11
+ const XML_KEY_USE_LAYOUT = 'use_layout';
12
+ const XML_KEY_CAN_CLEAN = 'can_clean';
13
+ const XML_KEY_CAN_LAYOUT = 'can_layout';
14
+ const XML_KEY_GBR_CLEAN = 'gbr_clean';
15
+ const XML_KEY_GBR_LAYOUT = 'gbr_layout';
16
+ const XML_KEY_DEU_CLEAN = 'deu_clean';
17
+ const XML_KEY_DEU_LAYOUT = 'deu_layout';
18
+ const XML_KEY_IRL_CLEAN = 'irl_clean';
19
+ const XML_KEY_IRL_LAYOUT = 'irl_layout';
20
+ const XML_KEY_MANUAL_ADDRESS_ENTRY = 'manual_address_entry';
21
+ const XML_KEY_ENABLE_ATI = 'enable_ati';
22
+ const XML_KEY_USE_PROXY = 'use_proxy';
23
+ const XML_KEY_PROXYNAME = 'proxyname';
24
+ const XML_KEY_PROXYPORT = 'proxyport';
25
+ const XML_KEY_PROXYUSER = 'proxyuser';
26
+ const XML_KEY_PROXYPASSWORD = 'proxypassword';
27
+ const XML_KEY_LVR = 'lvr';
28
+ const XML_KEY_IR_DISP = 'ir_disp';
29
+
30
+ public function getServiceType()
31
+ {
32
+ return $this->getSettingAsString(self::XML_KEY_SERVICE);
33
+ }
34
+
35
+ public function getOnDemandToken()
36
+ {
37
+ return $this->getSettingAsString(self::XML_KEY_TOKEN);
38
+ }
39
+
40
+ public function getOnDemandEndpoint()
41
+ {
42
+ return $this->getSettingAsString(self::XML_KEY_ENDPOINT);
43
+ }
44
+
45
+ public function isUserInteractionEnabled()
46
+ {
47
+ return $this->getSettingAsBoolean(self::XML_KEY_USER_INTERACTION);
48
+ }
49
+
50
+ public function isATIEnabled()
51
+ {
52
+ return $this->getSettingAsBoolean(self::XML_KEY_ENABLE_ATI);
53
+ }
54
+
55
+ public function isUSAEnabled()
56
+ {
57
+ return $this->getSettingAsBoolean(self::XML_KEY_USA_CLEAN);
58
+ }
59
+
60
+ public function areUSDataSetsEnabled()
61
+ {
62
+ return $this->isATIEnabled() || $this->isUSAEnabled();
63
+ }
64
+
65
+ public function getUSALayout()
66
+ {
67
+ return $this->getSettingAsString(self::XML_KEY_USA_LAYOUT);
68
+ }
69
+
70
+ public function getUSELayout()
71
+ {
72
+ return $this->getSettingAsString(self::XML_KEY_USE_LAYOUT);
73
+ }
74
+
75
+ public function isCANEnabled()
76
+ {
77
+ return $this->getSettingAsBoolean(self::XML_KEY_CAN_CLEAN);
78
+ }
79
+
80
+ public function getCANLayout()
81
+ {
82
+ return $this->getSettingAsString(self::XML_KEY_CAN_LAYOUT);
83
+ }
84
+
85
+ public function isGBREnabled()
86
+ {
87
+ return $this->getSettingAsBoolean(self::XML_KEY_GBR_CLEAN);
88
+ }
89
+
90
+ public function getGBRLayout()
91
+ {
92
+ return $this->getSettingAsString(self::XML_KEY_GBR_LAYOUT);
93
+ }
94
+
95
+ public function isDEUEnabled()
96
+ {
97
+ return $this->getSettingAsBoolean(self::XML_KEY_DEU_CLEAN);
98
+ }
99
+
100
+ public function getDEULayout()
101
+ {
102
+ return $this->getSettingAsString(self::XML_KEY_DEU_LAYOUT);
103
+ }
104
+
105
+ public function isIRLEnabled()
106
+ {
107
+ return $this->getSettingAsBoolean(self::XML_KEY_IRL_CLEAN);
108
+ }
109
+
110
+ public function getIRLLayout()
111
+ {
112
+ return $this->getSettingAsString(self::XML_KEY_IRL_LAYOUT);
113
+ }
114
+
115
+ public function isManualEntryEnabled()
116
+ {
117
+ return $this->getSettingAsBoolean(self::XML_KEY_MANUAL_ADDRESS_ENTRY);
118
+ }
119
+
120
+ public function isUsingProxy()
121
+ {
122
+ return $this->getSettingAsBoolean(self::XML_KEY_USE_PROXY);
123
+ }
124
+
125
+ public function getProxyName()
126
+ {
127
+ return $this->getSettingAsString(self::XML_KEY_PROXYNAME);
128
+ }
129
+
130
+ public function getProxyPort()
131
+ {
132
+ return $this->getSettingAsString(self::XML_KEY_PROXYPORT);
133
+ }
134
+
135
+ public function getProxyUser()
136
+ {
137
+ return $this->getSettingAsString(self::XML_KEY_PROXYUSER);
138
+ }
139
+
140
+ public function getProxyPassword()
141
+ {
142
+ return $this->getSettingAsString(self::XML_KEY_PROXYPASSWORD);
143
+ }
144
+
145
+ public function getLVRCheckLineNumber()
146
+ {
147
+ return $this->getSettingAsString(self::XML_KEY_LVR);
148
+ }
149
+
150
+ public function getNumberOfInteraotionRequiredDisplayLines()
151
+ {
152
+ return $this->getSettingAsString(self::XML_KEY_IR_DISP);
153
+ }
154
+
155
+ private function getSettingAsString($key)
156
+ {
157
+ return (string)Mage::getStoreConfig(self::XML_PATH_TO_SETTINGS . $key);
158
+ }
159
+
160
+ private function getSettingAsBoolean($key)
161
+ {
162
+ return (bool)Mage::getStoreConfig(self::XML_PATH_TO_SETTINGS . $key);
163
+ }
164
+ }
app/code/community/EDQ/AddressValidation/Model/Customer.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Customer extends Mage_Core_Model_Abstract
3
+ {
4
+ protected $_eventPrefix = 'addressvalidation_customer';
5
+ protected $_evenetObject = 'customer';
6
+
7
+ public function _construct()
8
+ {
9
+ $this->_init('addressvalidation/customer');
10
+ }
11
+
12
+ protected function _beforeSave()
13
+ {
14
+ parent::_beforeSave();
15
+ if($this->isObjectNew())
16
+ {
17
+ $this->setData('timestamp', Varien_Date::now());
18
+ }
19
+ return $this;
20
+ }
21
+ }
app/code/community/EDQ/AddressValidation/Model/DataCenters.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_DataCenters
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value' => 'uk', 'label'=>Mage::helper('adminhtml')->__('United Kingdom')),
13
+ array('value' => 'us', 'label'=>Mage::helper('adminhtml')->__('United States')),
14
+ );
15
+ }
16
+
17
+ /**
18
+ * Get options in "key-value" format
19
+ *
20
+ * @return array
21
+ */
22
+ public function toArray()
23
+ {
24
+ return array(
25
+ 'uk' => Mage::helper('adminhtml')->__('United Kingdom'),
26
+ 'us' => Mage::helper('adminhtml')->__('United States'),
27
+ );
28
+ }
29
+ }
app/code/community/EDQ/AddressValidation/Model/DoCanSearchParameters.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class DoCanSearchParameters
4
+ {
5
+ public $Country;
6
+ public $Layout;
7
+
8
+ public function __construct($country, $layout)
9
+ {
10
+ $this->Country = $country;
11
+ $this->Layout = $layout;
12
+ }
13
+ }
app/code/community/EDQ/AddressValidation/Model/Observer.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Observer
3
+ {
4
+ public function adminhtmlBlockSystemConfigInitTabSectionsBefore(Varien_Event_Observer $observer)
5
+ {
6
+ //get init sections and tabs
7
+ $config = $observer->getConfig();
8
+
9
+ //get tab 'experiandataquality'
10
+ $experianDataQualityTab = $config->getNode('tabs/experiandataquality');
11
+
12
+ if(!$experianDataQualityTab)
13
+ {
14
+ $new_tab_xml = new Mage_Core_Model_Config_Element('
15
+ <experiandataquality translate="label">
16
+ <label>Experian Data Quality</label>
17
+ <sort_order>9999</sort_order>
18
+ </experiandataquality>
19
+ ');
20
+
21
+ $tabs = $config->getNode('tabs');
22
+ $tabs->appendChild($new_tab_xml);
23
+ }
24
+
25
+ return $this;
26
+ }
27
+
28
+ public function customerAddressSaveAfter(Varien_Event_Observer $observer)
29
+ {
30
+ if(!session_id())
31
+ {
32
+ return;
33
+ }
34
+
35
+ $isModuleEnable = Mage::helper('core')->isModuleOutputEnabled('EDQ_AddressValidation');
36
+ if(!$isModuleEnable) { return; }
37
+
38
+ $countryId = $observer->getData('customer_address')->getData('country_id');
39
+
40
+ if( ($countryId === 'US' && $this->_getSettings()->areUSDataSetsEnabled())
41
+ || ($countryId === 'CA' && $this->_getSettings()->isCANEnabled()))
42
+ {
43
+ $customerId = $observer->getData('customer_address')->getData('customer_id');
44
+
45
+ $getEdqInfoMatrixFor = 'getEdqInfoMatrixFor' . $customerId;
46
+ $edqInfoArray = Mage::getSingleton('adminhtml/session')->$getEdqInfoMatrixFor();
47
+
48
+ $edqInfo = null;
49
+ $entityId = $observer->getData('customer_address')->getData('entity_id');
50
+ $postIndex = filter_var($observer->getData('customer_address')->getData('post_index'), FILTER_SANITIZE_NUMBER_INT);
51
+ if(is_array($edqInfoArray) && array_key_exists($postIndex, $edqInfoArray))
52
+ {
53
+ $edqInfo = $edqInfoArray[$postIndex];
54
+ }
55
+ $this->_getService()->insertIntoDataBase($entityId, $edqInfo);
56
+
57
+ if($edqInfo !== null)
58
+ {
59
+ $unsEdqInfoMatrixFor = 'unsEdqInfoMatrixFor' . $customerId;
60
+ Mage::getSingleton('adminhtml/session')->$unsEdqInfoMatrixFor();
61
+ }
62
+ }
63
+ }
64
+
65
+ private function _getService()
66
+ {
67
+ return Mage::getModel('addressvalidation/Service');
68
+ }
69
+
70
+ private function _getSettings()
71
+ {
72
+ return Mage::helper('addressvalidation/Settings');
73
+ }
74
+ }
app/code/community/EDQ/AddressValidation/Model/Quote.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_Addressvalidation_Model_Quote extends Mage_Core_Model_Abstract
3
+ {
4
+ protected $_eventPrefix = 'addressvalidation_quote';
5
+ protected $_evenetObject = 'customer';
6
+
7
+ public function _construct()
8
+ {
9
+ $this->_init('addressvalidation/quote');
10
+ }
11
+
12
+ protected function _beforeSave()
13
+ {
14
+ parent::_beforeSave();
15
+ if($this->isObjectNew())
16
+ {
17
+ $this->setData('timestamp', Varien_Date::now());
18
+ }
19
+ return $this;
20
+ }
21
+ }
app/code/community/EDQ/AddressValidation/Model/Resource/Customer.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Resource_Customer extends Mage_Core_Model_Resource_Db_Abstract
3
+ {
4
+ public function _construct()
5
+ {
6
+ $this->_init('addressvalidation/customer', 'customer_id');
7
+ }
8
+ }
app/code/community/EDQ/AddressValidation/Model/Resource/Customer/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Resource_Customer_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
3
+ {
4
+ protected function _construct()
5
+ {
6
+ $this->_init('addressvalidation/customer');
7
+ }
8
+ }
app/code/community/EDQ/AddressValidation/Model/Resource/Quote.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Resource_Quote extends Mage_Core_Model_Resource_Db_Abstract
3
+ {
4
+ public function _construct()
5
+ {
6
+ $this->_init('addressvalidation/quote', 'quote_id');
7
+ }
8
+ }
app/code/community/EDQ/AddressValidation/Model/Resource/Quote/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_Resource_Quote_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
3
+ {
4
+ protected function _construct()
5
+ {
6
+ $this->_init('addressvalidation/quote');
7
+ }
8
+ }
app/code/community/EDQ/AddressValidation/Model/Service.php ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/ServiceFactory.php');
3
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/CanSearchRequest.php');
4
+ include_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetLayoutsRequest.php');
5
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php');
6
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/RefineRequest.php');
7
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetAddressRequest.php');
8
+
9
+ class EDQ_AddressValidation_Model_Service
10
+ {
11
+ public function getLayouts(GetLayoutsRequest $getLayoutsRequest)
12
+ {
13
+ $service = ExperianDataQuality_ServiceFactory::createService();
14
+ return $service->doGetLayouts($getLayoutsRequest);
15
+ }
16
+
17
+ public function canSearch(CanSearchRequest $canSearchRequest, $service = NULL, $token = NULL)
18
+ {
19
+ $service = ExperianDataQuality_ServiceFactory::createService($service, $token);
20
+ return $service->doCanSearch($canSearchRequest);
21
+ }
22
+
23
+ public function searchAction(SearchRequest $searchRequest, $secondRound = false, $searchAddress = "", $isSingleLine = FALSE)
24
+ {
25
+ try
26
+ {
27
+ $searchString = '';
28
+ if($searchAddress === "")
29
+ {
30
+ $searchString = $this->_parseDoSearchRequest($searchRequest);
31
+ }
32
+ else
33
+ {
34
+ $asSearch = explode(",", $searchAddress);
35
+ $bFirst = TRUE;
36
+
37
+ if (isset($asSearch))
38
+ {
39
+ if (is_array($asSearch))
40
+ {
41
+ foreach ($asSearch AS $sSearch)
42
+ {
43
+ if (!$bFirst)
44
+ {
45
+ $searchString = $searchString . '|';
46
+ }
47
+
48
+ $searchString = $searchString . $sSearch;
49
+ $bFirst = FALSE;
50
+ }
51
+ }
52
+ else
53
+ {
54
+ $searchString = $asSearch;
55
+ }
56
+ }
57
+ }
58
+
59
+ $service = ExperianDataQuality_ServiceFactory::createService();
60
+ $doSearchResult = $service->doSearch($searchRequest, $searchString);
61
+
62
+ if($isSingleLine)
63
+ {
64
+ return $doSearchResult;
65
+ }
66
+
67
+ $cleanResult = array();
68
+ $cleanResult['matchType'] = $doSearchResult->MatchType;
69
+
70
+ if (($cleanResult['matchType'] === "Verified") || ($cleanResult['matchType'] === "InteractionRequired"))
71
+ {
72
+ $cleanResult['dpvStatus'] = $doSearchResult->DPVStatus;
73
+ $cleanResult['isMissingSubPrem'] = $doSearchResult->MissingSubPremise;
74
+ $cleanResult['cleanAddress'] = $doSearchResult->AddressLineDictionary;
75
+ }
76
+ else
77
+ {
78
+ foreach($doSearchResult->PickListEntries as $item) {
79
+ $cleanResult['picklist'][] = array(
80
+ 'partialtext' => $item->PartialAddress,
81
+ 'addresstext' => $item->PickList,
82
+ 'postcode' => $item->Postcode,
83
+ 'moniker' => $item->Moniker,
84
+ 'fulladdress' => ($item->FullAddress ? True : False)
85
+ );
86
+ }
87
+ }
88
+
89
+ if($cleanResult['matchType'] === 'Verified' || $cleanResult['matchType'] === 'InteractionRequired')
90
+ {
91
+ if($searchRequest->DataSet === 'CAN' && !$this->_aptCheck($cleanResult['cleanAddress']))
92
+ {
93
+ $cleanResult['matchType'] = 'AptAppend';
94
+ }
95
+ else if($cleanResult['matchType'] === 'InteractionRequired' && $secondRound)
96
+ {
97
+ $cleanResult['matchType'] = 'Verified';
98
+ }
99
+ }
100
+ }
101
+ catch (Exception $ex)
102
+ {
103
+
104
+ $cleanResult['matchType'] = 'error';
105
+ $cleanResult['error'] = Mage::getSingleton('core/translate')
106
+ ->translate(array('There was an error reaching the Experian Address Verification service. See Magento logs for details.'));
107
+ $this->handleException($ex);
108
+ }
109
+
110
+ return $cleanResult;
111
+ }
112
+
113
+ public function refine(RefineRequest $refineRequest, $isSingleLine = FALSE)
114
+ {
115
+ try
116
+ {
117
+ $service = ExperianDataQuality_ServiceFactory::createService();
118
+ $refineResult = $service->doRefine($refineRequest);
119
+
120
+ if($isSingleLine)
121
+ {
122
+ return $refineResult;
123
+ }
124
+
125
+ if($refineResult->Total === 1 && $refineResult->PickListEntries[0]->FullAddress === TRUE)
126
+ {
127
+ $getAddressRequest = new GetAddressRequest();
128
+ $getAddressRequest->DataSet = $refineRequest->DataSet;
129
+ $getAddressRequest->Moniker = $refineRequest->Moniker;
130
+
131
+ return $this->getAddress($getAddressRequest);
132
+ }
133
+ else
134
+ {
135
+ $returnResult['matchType'] = 'PremisesPartial';
136
+ foreach($refineResult->PickListEntries as $item) {
137
+ $returnResult['picklist'][] = array(
138
+ 'partialtext' => $item->PartialAddress,
139
+ 'addresstext' => $item->Picklist,
140
+ 'postcode' => $item->Postcode,
141
+ 'moniker' => $item->Moniker,
142
+ 'fulladdress' => ($item->FullAddress ? True : False)
143
+ );
144
+ }
145
+ }
146
+ }
147
+ catch (Exception $ex)
148
+ {
149
+ $returnResult['matchType'] = 'error';
150
+ $returnResult['error'] = Mage::getSingleton('core/translate')
151
+ ->translate(array('There was an error reaching the Experian Address Verification service. See Magento logs for details.'));
152
+ $this->handleException($ex);
153
+ }
154
+
155
+ return $returnResult;
156
+
157
+ }
158
+
159
+ public function getAddress(GetAddressRequest $getAddressRequest, $isSingleLine = FALSE)
160
+ {
161
+ $returnResult = array();
162
+ try
163
+ {
164
+ $service = ExperianDataQuality_ServiceFactory::createService();
165
+ $doGetAddress = $service->doGetAddress($getAddressRequest);
166
+
167
+ if($isSingleLine)
168
+ {
169
+ return $doGetAddress;
170
+ }
171
+
172
+ $returnResult['matchType'] = $doGetAddress->MatchType;
173
+ $returnResult['dpvStatus'] = $doGetAddress->DPVStatus;
174
+ $returnResult['cleanAddress'] = $doGetAddress->AddressLineDictionary;
175
+ }
176
+ catch (Exception $ex)
177
+ {
178
+ $returnResult['matchType'] = 'error';
179
+ $returnResult['error'] = Mage::getSingleton('core/translate')
180
+ ->translate(array('There was an error reaching the Experian Address Verification service. See Magento logs for details.'));
181
+ $this->handleException($ex);
182
+ }
183
+
184
+ return $returnResult;
185
+ }
186
+
187
+ /**
188
+ * Get the searchText for a PremisesPartial result
189
+ *
190
+ * @param Array $data The search data
191
+ * @param string $apt The desired apartment number
192
+ * @return mixed
193
+ */
194
+ public function getPremisesPartialSearchText($data, $apt)
195
+ {
196
+ $partialAddress = $this->_getPartialText($data);
197
+ $strippedZipText = $this->_stripZip($partialAddress);
198
+
199
+ // Replace an instance of ',' with '# $apt,' from the $strippedZipText
200
+ // Returns the full address search text
201
+ return preg_replace("/,/", " # " . $apt . ",", $strippedZipText);
202
+ }
203
+
204
+ /**
205
+ * Get the searchText for a StreetPartial result
206
+ *
207
+ * @param Array $data The search data
208
+ * @param string $street The desired street number
209
+ * @return string
210
+ */
211
+ public function getStreetPartialSearchText($data, $street)
212
+ {
213
+ $partialAddress = $this->_getPartialText($data);
214
+ $strippedZipText = $this->_stripZip($partialAddress);
215
+
216
+ // Returns the full address search text
217
+ return $street . " " . $strippedZipText;
218
+ }
219
+
220
+ public function getRegion($regionId)
221
+ {
222
+ return Mage::getModel('directory/region')->load($regionId)->getCode();
223
+ }
224
+
225
+ public function getRegionId($regionCode, $countryCode)
226
+ {
227
+ return Mage::getModel('directory/region')->loadByCode($regionCode, $countryCode)->getId();
228
+ }
229
+
230
+ public function insertIntoDataBase($id = NULL, $data = NULL)
231
+ {
232
+ try
233
+ {
234
+ $isBilling = $this->_getSession()->getIsBilling();
235
+ $isCheckout = $this->_getSession()->getIsCheckout();
236
+
237
+ if($data === NULL)
238
+ {
239
+ $data = $this->_getSession()->getEdqInfo();
240
+
241
+ if($data === NULL) { return; }
242
+ }
243
+
244
+ if($id === NULL && $isCheckout)
245
+ {
246
+ $id = $isBilling ? Mage::getSingleton('checkout/type_onepage')->getQuote()->getBillingAddress()->getQuoteId()
247
+ : Mage::getSingleton('checkout/type_onepage')->getQuote()->getShippingAddress()->getQuoteId();
248
+ }
249
+
250
+ if(!$id)
251
+ {
252
+ throw new Exception(Mage::getSingleton('core/translate')
253
+ ->translate(array('There is no Entity Id, therefore cannot save any data.')));
254
+ }
255
+
256
+ if($isCheckout)
257
+ {
258
+ $table = Mage::getModel('addressvalidation/quote');
259
+ $table->setAddress_type($isBilling ? 'Billing' : 'Shipping');
260
+ }
261
+ else
262
+ {
263
+ $table = Mage::getModel('addressvalidation/customer');
264
+ }
265
+
266
+ $table->setEntity_id($id);
267
+ $table->setMatchtype($this->_getMethods()->getValueOrEmptyString('matchType', $data));
268
+ $table->setAdditionaldata($this->_getMethods()->getValueOrEmptyString('additionalData', $data));
269
+ $table->save();
270
+
271
+ $this->_getSession()->unsEdqInfo();
272
+ }
273
+ catch (Exception $ex)
274
+ {
275
+ $this->handleException($ex);
276
+ }
277
+ }
278
+
279
+ public function handleException(Exception $ex)
280
+ {
281
+ Mage::logException($ex);
282
+ Mage::log($ex->getMessage() . PHP_EOL . $ex->getTraceAsString(), null, 'ExperianDataQualityExceptions.log', true);
283
+ }
284
+
285
+ /**
286
+ * Returns the partialtext from given data
287
+ *
288
+ * @param Array $data Contains response data for returned picklist values from the OnDemand service
289
+ * @return string $partialText The partial address captured so far
290
+ */
291
+ private function _getPartialText($data)
292
+ {
293
+ $partialText = "";
294
+
295
+ foreach($data["picklist"] as $add)
296
+ {
297
+ if(!$add["fulladdress"])
298
+ {
299
+ $temp = $add["partialtext"];
300
+
301
+ // Remove the range [ex. '1 ... 100 ' or '1 ... 100-'] from the front of the address
302
+ $temp = preg_split("/[0-9a-zA-Z]+\s[\.\.\.]+\s[0-9a-zA-Z]+(\s|-)/", $temp);
303
+
304
+ // temp[0] will hold the range
305
+ // temp[1] will hold the partial address
306
+ $partialText = $temp[1];
307
+
308
+ break;
309
+ }
310
+ else
311
+ {
312
+ $partialText = $data["picklist"][0]["partialtext"];
313
+
314
+ break;
315
+ }
316
+ }
317
+
318
+ return $partialText;
319
+ }
320
+
321
+ /**
322
+ * Remove the zip+4 code from a given address
323
+ *
324
+ * @param string $address A full address
325
+ * @return string The address without the zip+4 code
326
+ */
327
+ private function _stripZip($address)
328
+ {
329
+ return preg_replace("/-\d{4}$/", "", $address);
330
+ }
331
+
332
+ private function _aptCheck($address)
333
+ {
334
+ $lvr = $this->_getSettings()->getLVRCheckLineNumber();
335
+
336
+ $isApt = (isset($address['Line' . ($lvr - 1)]) && $address['Line' . ($lvr - 1)] !== '') ? true : false;
337
+
338
+ if ($isApt)
339
+ {
340
+ return preg_match("/\|?\d+\s*-\s*\d+/", implode('|', $address));
341
+ }
342
+
343
+ return true;
344
+ }
345
+
346
+ private function _parseDoSearchRequest(SearchRequest $searchRequest)
347
+ {
348
+ if (isset($searchRequest) === FALSE)
349
+ {
350
+ throw new \Exception("searchRequest");
351
+ }
352
+
353
+ $delimiter = "|";
354
+
355
+ switch ($searchRequest->DataSet)
356
+ {
357
+ case 'US':
358
+ case 'CA':
359
+ case 'USA':
360
+ case 'CAN':
361
+ return $searchRequest->Street1 . $delimiter .
362
+ $searchRequest->Street2 . $delimiter .
363
+ $searchRequest->City . $delimiter .
364
+ $searchRequest->State . $delimiter .
365
+ $searchRequest->Postcode;
366
+ case 'GB':
367
+ case 'GBR':
368
+ return $searchRequest->Street1 . $delimiter .
369
+ $searchRequest->BuildingNumberOrName . $delimiter .
370
+ $delimiter .
371
+ $delimiter .
372
+ $searchRequest->Postcode . $searchRequest->TownOrLacality;
373
+ case 'DE':
374
+ case 'DEU':
375
+ return $searchRequest->Street1 . $delimiter .
376
+ $searchRequest->BuildingNumberOrName . $delimiter .
377
+ $delimiter .
378
+ $delimiter .
379
+ $searchRequest->Postcode . $searchRequest->TownOrLacality;
380
+ case 'IE':
381
+ case 'IRL':
382
+ return $searchRequest->Street1 . $delimiter .
383
+ $searchRequest->BuildingNumberOrName . $delimiter .
384
+ $delimiter .
385
+ $delimiter .
386
+ $searchRequest->TownOrLacality;
387
+ default:
388
+ return '';
389
+ }
390
+ }
391
+
392
+ private function _getMethods()
393
+ {
394
+ return Mage::helper('addressvalidation/Methods');
395
+ }
396
+
397
+ private function _getSettings()
398
+ {
399
+ return Mage::helper('addressvalidation/Settings');
400
+ }
401
+
402
+ private function _getSession()
403
+ {
404
+ return Mage::getSingleton('core/session');
405
+ }
406
+ }
app/code/community/EDQ/AddressValidation/Model/ServiceProviders.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_AddressValidation_Model_ServiceProviders
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value' => 'proondemand', 'label'=>Mage::helper('adminhtml')->__('Pro On Demand'))
13
+ );
14
+ }
15
+
16
+ /**
17
+ * Get options in "key-value" format
18
+ *
19
+ * @return array
20
+ */
21
+ public function toArray()
22
+ {
23
+ return array(
24
+ 'proondemand' => Mage::helper('adminhtml')->__('Pro On Demand')
25
+ );
26
+ }
27
+ }
app/code/community/EDQ/AddressValidation/Model/Validate.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/CanSearchRequest.php';
3
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetLayoutsRequest.php';
4
+ include_once 'DoCanSearchParameters.php';
5
+
6
+ class EDQ_AddressValidation_Model_Validate extends Mage_Core_Model_Config_Data
7
+ {
8
+ public function _beforeSave()
9
+ {
10
+ $moduleName = 'EDQ_AddressValidation';
11
+
12
+ if(!Mage::helper('core')->isModuleOutputEnabled($moduleName)){
13
+ return parent::_beforeSave();
14
+ }
15
+
16
+ $data = array(
17
+ "ServiceType" => $this->getFieldsetDataValue('service_type'),
18
+
19
+ "Token" => $this->getFieldsetDataValue('token'),
20
+ "Endpoint" => $this->getFieldsetDataValue('endpoint'),
21
+
22
+ "IsProxyEnabled" => $this->getFieldsetDataValue('use_proxy'),
23
+
24
+ "IsUSAEnabled" => $this->getFieldsetDataValue('usa_clean'),
25
+ "USALayout" => $this->getFieldsetDataValue('usa_layout'),
26
+
27
+ "IsATIEnabled" => $this->getFieldsetDataValue('enable_ati'),
28
+ "USELayout" => $this->getFieldsetDataValue('use_layout'),
29
+
30
+ "IsCANEnabled" => $this->getFieldsetDataValue('can_clean'),
31
+ "CANLayout" => $this->getFieldsetDataValue('can_layout'),
32
+
33
+ "IsGRBEnabled" => $this->getFieldsetDataValue('gbr_clean'),
34
+ "GRBLayout" => $this->getFieldsetDataValue('gbr_layout'),
35
+
36
+ "IsDEUEnabled" => $this->getFieldsetDataValue('deu_clean'),
37
+ "DEULayout" => $this->getFieldsetDataValue('deu_layout'),
38
+
39
+ "IsIRLEnabled" => $this->getFieldsetDataValue('irl_clean'),
40
+ "IRLLayout" => $this->getFieldsetDataValue('irl_layout'),
41
+
42
+ "ProxyName" => $this->getFieldsetDataValue('proxyname'),
43
+ "ProxyPort" => $this->getFieldsetDataValue('proxyport'),
44
+
45
+ "PorxyUser" => $this->getFieldsetDataValue('proxyuser'),
46
+ "ProxyPassword" => $this->getFieldsetDataValue('proxypassword')
47
+ );
48
+
49
+ $errors = array();
50
+ $validationResult = $this->ValidateEDQFields($data, $errors);
51
+
52
+ if($validationResult == false)
53
+ {
54
+ array_push($errors, $this->_getTranslation('The configuration has not been saved.'));
55
+ $errorMessage = implode("\n", $errors);
56
+ Mage::throwException($errorMessage);
57
+ return false;
58
+ }
59
+
60
+ return parent::_beforeSave();
61
+ }
62
+
63
+ public function ValidateEDQFields($data, &$errors)
64
+ {
65
+ if($data['IsProxyEnabled'] == 1)
66
+ {
67
+ $this->_ifEmptyAddError($data['ProxyName'], $errors, $this->_getTranslation('Proxy URL') . $this->_getTranslation(' cannot be empty.'));
68
+ $this->_ifEmptyAddError($data['ProxyPort'], $errors, $this->_getTranslation('Proxy Port') . $this->_getTranslation(' cannot be empty.'));
69
+ $this->_ifEmptyAddError($data['PorxyUser'], $errors, $this->_getTranslation('Proxy Username') . $this->_getTranslation(' cannot be empty.'));
70
+ $this->_ifEmptyAddError($data['PorxyUser'], $errors, $this->_getTranslation('Proxy Password') . $this->_getTranslation(' cannot be empty.'));
71
+
72
+ if(count($errors) > 0) { return false; }
73
+ }
74
+
75
+ $doCanSearchParametersArray = array();
76
+
77
+ $this->_insertParameterIfEnabledFor('USA', $data['IsUSAEnabled'], $data['USALayout'], $doCanSearchParametersArray);
78
+ $this->_insertParameterIfEnabledFor('USE', $data['IsATIEnabled'], $data['USELayout'], $doCanSearchParametersArray);
79
+ $this->_insertParameterIfEnabledFor('CAN', $data['IsCANEnabled'], $data['CANLayout'], $doCanSearchParametersArray);
80
+ $this->_insertParameterIfEnabledFor('GBR', $data['IsGRBEnabled'], $data['GRBLayout'], $doCanSearchParametersArray);
81
+ $this->_insertParameterIfEnabledFor('DEU', $data['IsDEUEnabled'], $data['DEULayout'], $doCanSearchParametersArray);
82
+ $this->_insertParameterIfEnabledFor('IRL', $data['IsIRLEnabled'], $data['IRLLayout'], $doCanSearchParametersArray);
83
+
84
+ if(count($doCanSearchParametersArray) == 0) { return true; }
85
+
86
+ if($data["ServiceType"] === 'proondemand')
87
+ {
88
+ $this->_ifEmptyAddError($data['Token'], $errors, $this->_getTranslation('On Demand Token') . $this->_getTranslation(' cannot be empty.'));
89
+ $this->_ifEmptyAddError($data['Endpoint'], $errors, $this->_getTranslation('On Demand Endpoint') . $this->_getTranslation(' cannot be empty.'));
90
+ }
91
+
92
+ if($data['IsUSAEnabled'] == 1 && $data['IsATIEnabled'] == 1)
93
+ {
94
+ array_push($errors, $this->_getTranslation('Both USA Clean and Enabled ATI settings cannot be enabled at the same time.'));
95
+ }
96
+
97
+ if(count($errors) > 0) { return false; }
98
+
99
+ foreach ($doCanSearchParametersArray as $doCanSearchParameters)
100
+ {
101
+ $soapFault = '';
102
+ $soapString = '';
103
+
104
+ $canSearchRequest = new CanSearchRequest();
105
+ $canSearchRequest->DataSet = $doCanSearchParameters->Country;
106
+ $canSearchRequest->Layout = $doCanSearchParameters->Layout;
107
+ $canSearchRequest->Service = $data["ServiceType"];
108
+ $canSearchRequest->Location = $data["Endpoint"];
109
+
110
+ try
111
+ {
112
+ $doCanSearchResult = $this->_getService()->canSearch($canSearchRequest, $data["ServiceType"], $data['Token']);
113
+ }
114
+ catch (SoapFault $e)
115
+ {
116
+ $soapString = $e->faultstring;
117
+ $soapFault = $e->faultcode;
118
+ }
119
+
120
+ if(!$this->_isNullOrEmptyString($soapFault))
121
+ {
122
+ if(strcmp(strtoupper($soapFault), strtoupper('AuthorizationFailed')) == 0)
123
+ {
124
+ array_push($errors,$this->_getTranslation('Your account is not authorized to use this Datacenter.'));
125
+ break;
126
+ }
127
+ else if(strcmp(strtoupper($soapFault), strtoupper('AuthenticationFailed')) == 0)
128
+ {
129
+ if(HelperMethods::startsWith('User has reached maximum number of failed log on attempts', $soapString))
130
+ {
131
+ array_push($errors, $this->_getTranslation('User has reached maximum number of failed log on attempts.'));
132
+ break;
133
+ }
134
+ array_push($errors, $this->_getTranslation('Your On Demand Token is incorrect.'));
135
+ break;
136
+ }
137
+ else
138
+ {
139
+ array_push($errors, $this->_getTranslation('There was an error reaching the Experian Address Verification service. See Magento logs for details.'));
140
+ break;
141
+ }
142
+ }
143
+ else if(!$this->_isNullOrEmptyString($doCanSearchResult->ErrorCode) || !$this->_isNullOrEmptyString($doCanSearchResult->ErrorDetail))
144
+ {
145
+ array_push($errors, $doCanSearchParameters->Layout . $this->_getTranslation(' is an incorrect layout.'));
146
+ }
147
+ }
148
+
149
+ return count($errors) === 0;
150
+ }
151
+
152
+ private function _insertParameterIfEnabledFor($country, $isEnabled, $layout, &$parameterArray)
153
+ {
154
+ if($isEnabled == 1)
155
+ {
156
+ if($this->_isNullOrEmptyString($layout))
157
+ {
158
+ $action = 'get' . $country . 'Layout';
159
+ if(is_callable(array($this->_getSettings(), $action)))
160
+ {
161
+ $layout = $this->_getSettings()->$action();
162
+ }
163
+ }
164
+ array_push($parameterArray, new DoCanSearchParameters($country, $layout));
165
+ }
166
+ }
167
+
168
+ private function _ifEmptyAddError($value, &$errors, $message)
169
+ {
170
+ if($this->_isNullOrEmptyString($value))
171
+ {
172
+ array_push($errors, $this->_getTranslation($message));
173
+ }
174
+ }
175
+
176
+ private function _isNullOrEmptyString($fieldValue)
177
+ {
178
+ return (!isset($fieldValue) || trim($fieldValue)==='');
179
+ }
180
+
181
+ private function _getTranslation($message)
182
+ {
183
+ return Mage::getSingleton('core/translate')->translate(array($message));
184
+ }
185
+
186
+ private function _getService()
187
+ {
188
+ return Mage::getModel('addressvalidation/Service');
189
+ }
190
+
191
+ private function _getSettings()
192
+ {
193
+ return Mage::helper('addressvalidation/Settings');
194
+ }
195
+ }
app/code/community/EDQ/AddressValidation/controllers/ProcessAdminController.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php');
3
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/RefineRequest.php');
4
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetAddressRequest.php');
5
+
6
+ /**
7
+ * ProcessAdminController
8
+ *
9
+ * EDQ_AddressValidation controller for backend touchpoints
10
+ */
11
+ class EDQ_AddressValidation_ProcessAdminController extends Mage_Adminhtml_Controller_Action
12
+ {
13
+ public function searchSingleLineAction()
14
+ {
15
+ try
16
+ {
17
+ $data = $this->getRequest()->getParams();
18
+
19
+ if(!$this->getRequest()->getPost() && empty($data))
20
+ {
21
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
22
+ }
23
+
24
+ $searchRequest = new SearchRequest();
25
+ $searchRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
26
+
27
+ if($searchRequest->DataSet === 'US' || $searchRequest->DataSet === 'CA')
28
+ {
29
+ $searchRequest->Street1 = $this->_getMethods()->getValueOrEmptyString('Line0', $data);
30
+ $searchRequest->Street2 = $this->_getMethods()->getValueOrEmptyString('Line1', $data);
31
+ $searchRequest->City = $this->_getMethods()->getValueOrEmptyString('Line2', $data);
32
+ $searchRequest->State = $this->_getService()->getRegion($this->_getMethods()->getValueOrEmptyString('Line3', $data));
33
+ $searchRequest->Postcode = $this->_getMethods()->getValueOrEmptyString('Line4', $data);
34
+ }
35
+ else
36
+ {
37
+ $searchRequest->Street1 = $this->_getMethods()->getValueOrEmptyString('Street1', $data);
38
+ $searchRequest->BuildingNumberOrName = $this->_getMethods()->getValueOrEmptyString('BuildingNumberOrName', $data);
39
+ $searchRequest->TownOrLacality = $this->_getMethods()->getValueOrEmptyString('Town', $data);
40
+ $searchRequest->Postcode = $this->_getMethods()->getValueOrEmptyString('Postcode', $data);
41
+ }
42
+
43
+ $searchResult = $this->_getService()->searchAction($searchRequest, FALSE, '', TRUE);
44
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
45
+ }
46
+ catch (Exception $ex)
47
+ {
48
+ $searchResult = array('error' => $ex->getMessage());
49
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
50
+ }
51
+ }
52
+
53
+ public function refineSingleLineAction()
54
+ {
55
+ try
56
+ {
57
+ $data = $this->getRequest()->getParams();
58
+
59
+ if(!$this->getRequest()->getPost() && empty($data))
60
+ {
61
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
62
+ }
63
+
64
+ $refineRequest = new RefineRequest();
65
+ $refineRequest->Moniker = $this->_getMethods()->getValueOrEmptyString('Moniker', $data);
66
+ $refineRequest->Refinement = $this->_getMethods()->getValueOrEmptyString('Refinement', $data);
67
+ $refineRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
68
+
69
+ $refineResult = $this->_getService()->refine($refineRequest, TRUE);
70
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($refineResult));
71
+ }
72
+ catch (Exception $ex)
73
+ {
74
+ $searchResult = array('error' => $ex->getMessage());
75
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
76
+ }
77
+ }
78
+
79
+ public function formatSingleLineAction()
80
+ {
81
+ try
82
+ {
83
+ $data = $this->getRequest()->getParams();
84
+
85
+ if(!$this->getRequest()->getPost() && empty($data))
86
+ {
87
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
88
+ }
89
+
90
+ $getAddressRequest = new GetAddressRequest();
91
+ $getAddressRequest->Moniker = $this->_getMethods()->getValueOrEmptyString('Moniker', $data);
92
+ $getAddressRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
93
+
94
+ $formatResult = $this->_getService()->getAddress($getAddressRequest, TRUE);
95
+
96
+ if(is_array($formatResult) && array_key_exists('matchType', $formatResult) && $formatResult['matchType'] === 'error')
97
+ {
98
+ throw new Exception($formatResult['error']);
99
+ }
100
+
101
+ if($getAddressRequest->DataSet == 'US' || $getAddressRequest->DataSet == 'CA')
102
+ {
103
+ $this->_collectAdditionalDataAndInserToDb($formatResult, $data);
104
+ }
105
+
106
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($formatResult));
107
+ }
108
+ catch (Exception $ex)
109
+ {
110
+ $searchResult = array('error' => $ex->getMessage());
111
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
112
+ }
113
+ }
114
+
115
+ private function _collectAdditionalDataAndInserToDb($searchResult, $data)
116
+ {
117
+ $edqInfo = array();
118
+ $edqInfo['matchType'] = $searchResult->MatchType;
119
+
120
+ if(isset($searchResult->AddressLineDictionary) && count($searchResult->AddressLineDictionary) < 5)
121
+ {
122
+ $edqInfo['error'] = $this->_getTranslation(
123
+ 'Invalid Layout. Make sure your layout conforms
124
+ to having as many street address lines as
125
+ your magento setup followed by three lines
126
+ containing City, State, Zip.');
127
+ throw new Exception($edqInfo['error']);
128
+ }
129
+ else
130
+ {
131
+ $key = 'Line';
132
+ $edqInfo['additionalData'] = '';
133
+ $size = count($searchResult->AddressLineDictionary);
134
+ for($j = 5; $j < $size; $j++)
135
+ {
136
+ $edqInfo['additionalData'] .= $searchResult->AddressLineDictionary[$key . $j] . '|';
137
+ }
138
+ }
139
+
140
+ $getEdqInfoMatrixFor = 'getEdqInfoMatrixFor' . $data['id'];
141
+ $edqInfoArray = $this->_getSession()->$getEdqInfoMatrixFor();
142
+
143
+ if(is_array($edqInfoArray) && array_key_exists($data['address_id'], $edqInfoArray))
144
+ {
145
+ $edqInfoArray[$data['address_id']] = $edqInfo;
146
+ }
147
+ else
148
+ {
149
+ $edqInfoArray = array();
150
+ $edqInfoArray[$data['address_id']] = $edqInfo;
151
+ }
152
+
153
+ $setEdqInfoMatrixFor = 'setEdqInfoMatrixFor' . $data['id'];
154
+ $this->_getSession()->$setEdqInfoMatrixFor($edqInfoArray);
155
+ }
156
+
157
+ private function _getService()
158
+ {
159
+ return Mage::getModel('addressvalidation/Service');
160
+ }
161
+
162
+ private function _getMethods()
163
+ {
164
+ return Mage::helper('addressvalidation/Methods');
165
+ }
166
+
167
+ private function _getTranslation($text)
168
+ {
169
+ return Mage::getSingleton('core/translate')->translate(array($text));
170
+ }
171
+
172
+ protected function _isAllowed() { return true; }
173
+ }
app/code/community/EDQ/AddressValidation/controllers/ProcessController.php ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php');
3
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/RefineRequest.php');
4
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetAddressRequest.php');
5
+
6
+ /**
7
+ * ProcessController
8
+ *
9
+ * EDQ_AddressValidation controller for frontend touchpoints
10
+ */
11
+ class EDQ_AddressValidation_ProcessController extends Mage_Core_Controller_Front_Action
12
+ {
13
+ public function searchSingleLineAction()
14
+ {
15
+ try
16
+ {
17
+ $data = $this->getRequest()->getParams();
18
+
19
+ if(!$this->getRequest()->getPost() && empty($data))
20
+ {
21
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
22
+ }
23
+
24
+ $searchRequest = new SearchRequest();
25
+ $searchRequest->Street1 = $this->_getMethods()->getValueOrEmptyString('Street1', $data);
26
+ $searchRequest->BuildingNumberOrName = $this->_getMethods()->getValueOrEmptyString('BuildingNumberOrName', $data);
27
+ $searchRequest->TownOrLacality = $this->_getMethods()->getValueOrEmptyString('Town', $data);
28
+ $searchRequest->Postcode = $this->_getMethods()->getValueOrEmptyString('Postcode', $data);
29
+ $searchRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
30
+
31
+ $searchResult = $this->_getService()->searchAction($searchRequest, FALSE, '', TRUE);
32
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
33
+ }
34
+ catch (Exception $ex)
35
+ {
36
+ $searchResult = array('error' => $ex->getMessage());
37
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
38
+ }
39
+ }
40
+
41
+ public function refineSingleLineAction()
42
+ {
43
+ try
44
+ {
45
+ $data = $this->getRequest()->getParams();
46
+
47
+ if(!$this->getRequest()->getPost() && empty($data))
48
+ {
49
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
50
+ }
51
+
52
+ $refineRequest = new RefineRequest();
53
+ $refineRequest->Moniker = $this->_getMethods()->getValueOrEmptyString('Moniker', $data);
54
+ $refineRequest->Refinement = $this->_getMethods()->getValueOrEmptyString('Refinement', $data);
55
+ $refineRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
56
+
57
+ $refineResult = $this->_getService()->refine($refineRequest, TRUE);
58
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($refineResult));
59
+ }
60
+ catch (Exception $ex)
61
+ {
62
+ $searchResult = array('error' => $ex->getMessage());
63
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
64
+ }
65
+ }
66
+
67
+ public function formatSingleLineAction()
68
+ {
69
+ try
70
+ {
71
+ $data = $this->getRequest()->getParams();
72
+
73
+ if(!$this->getRequest()->getPost() && empty($data))
74
+ {
75
+ throw new Exception($this->_getTranslation('Request parameters are empty or the request is not POST'));
76
+ }
77
+
78
+ $getAddressRequest = new GetAddressRequest();
79
+ $getAddressRequest->Moniker = $this->_getMethods()->getValueOrEmptyString('Moniker', $data);
80
+ $getAddressRequest->DataSet = $this->_getMethods()->getValueOrEmptyString('DataSet', $data);
81
+
82
+ $formatResult = $this->_getService()->getAddress($getAddressRequest, TRUE);
83
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($formatResult));
84
+ }
85
+ catch (Exception $ex)
86
+ {
87
+ $searchResult = array('error' => $ex->getMessage());
88
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($searchResult));
89
+ }
90
+ }
91
+
92
+ public function verifyAddressAction()
93
+ {
94
+ $isBilling = false;
95
+ $isCheckOut = false;
96
+ $data = $this->_getData($isBilling, $isCheckOut);
97
+
98
+ $this->_executeAddressVerification($data, $isBilling, $isCheckOut);
99
+ }
100
+
101
+ public function verifyBillingAction()
102
+ {
103
+ $isBilling = true;
104
+ $isCheckOut = true;
105
+
106
+ $data = $this->_getData($isBilling, $isCheckOut);
107
+ $this->_executeAddressVerification($data, $isBilling, $isCheckOut);
108
+ }
109
+
110
+ public function verifyShippingAction()
111
+ {
112
+ $isBilling = false;
113
+ $isCheckOut = true;
114
+
115
+ $data = $this->_getData($isBilling, $isCheckOut);
116
+ $this->_executeAddressVerification($data, $isBilling, $isCheckOut);
117
+ }
118
+
119
+ private function _executeAddressVerification($data, $isBilling, $isCheckOut)
120
+ {
121
+ $this->_getSession()->setInvalidInfo(FALSE);
122
+ $this->_getSession()->setIsCheckout($isCheckOut);
123
+ $searchRequest = $this->_getMethods()->createSearchRequest($data);
124
+
125
+ if(($searchRequest->DataSet === 'US' && $this->_getSettings()->areUSDataSetsEnabled())
126
+ || ($searchRequest->DataSet === 'CA' && $this->_getSettings()->isCANEnabled()))
127
+ {
128
+ $searchResult = $this->_getService()->searchAction($searchRequest);
129
+
130
+ if($searchResult['matchType'] === 'Verified'
131
+ || $searchResult['matchType'] === 'error'
132
+ || ($searchResult['matchType'] === 'InteractionRequired' && !$this->_getSettings()->isUserInteractionEnabled()))
133
+ {
134
+ $this->_saveAndReturn($data, $searchResult);
135
+ }
136
+ else if(!$this->_getSettings()->isUserInteractionEnabled())
137
+ {
138
+ $this->_saveAndReturn($data);
139
+ }
140
+ else
141
+ {
142
+ $this->_getSession()->setIsBilling($isBilling);
143
+ $this->_getSession()->setCustomerData($data);
144
+ $this->_getSession()->setSearchResult($searchResult);
145
+
146
+ $this->loadLayout();
147
+
148
+ if(!$isCheckOut)
149
+ {
150
+ $this->_initLayoutMessages('customer/session');
151
+ $layout = $this->getLayout();
152
+ $navigationBlock = $layout->getBlock('customer_account_navigation');
153
+ if ($navigationBlock)
154
+ {
155
+ $navigationBlock->setActive('customer/address');
156
+ }
157
+ }
158
+
159
+ $this->renderLayout();
160
+ return;
161
+ }
162
+ }
163
+ else
164
+ {
165
+ $this->_saveAndReturn($data);
166
+ }
167
+ }
168
+
169
+
170
+ public function acceptAction()
171
+ {
172
+ $this->_saveAndReturn(
173
+ $this->_getSession()->getCustomerData(),
174
+ $this->_getSession()->getSearchResult());
175
+ }
176
+
177
+ public function refinePremisesAction()
178
+ {
179
+ $data = $this->_getSession()->getCustomerData();
180
+ $searchData = $this->_getSession()->getSearchResult();
181
+
182
+ $apt = $this->getRequest()->getParam('refinetext');
183
+
184
+ $searchRequest = $this->_getMethods()->createSearchRequest($data);
185
+ $searchText = $this->_getService()->getPremisesPartialSearchText($searchData, $apt);
186
+
187
+ $searchResult = $this->_getService()->searchAction($searchRequest, true, $searchText);
188
+
189
+ if($searchResult['matchType'] === 'Verified' || $searchResult['matchType'] === 'error')
190
+ {
191
+ $this->_getSession()->setInvalidInfo(FALSE);
192
+ $this->_saveAndReturn($data, $searchResult);
193
+ return;
194
+ }
195
+
196
+ if($searchResult['matchType'] === 'PremisesPartial')
197
+ {
198
+ $this->_getSession()->setInvalidInfo(TRUE);
199
+ $this->_getSession()->setCustomerData($data);
200
+ $this->loadLayout()->renderLayout();
201
+ return;
202
+ }
203
+ else
204
+ {
205
+ $this->_getSession()->setInvalidInfo(TRUE);
206
+ $this->_getSession()->setCustomerData($data);
207
+ $this->_getSession()->setSearchResult($searchResult);
208
+ $this->loadLayout()->renderLayout();
209
+ return;
210
+ }
211
+ }
212
+
213
+ public function refineStreetAction()
214
+ {
215
+ $data = $this->_getSession()->getCustomerData();
216
+ $searchData = $this->_getSession()->getSearchResult();
217
+
218
+ $buildingNum = $this->getRequest()->getParam('refinetext');
219
+ $searchText = $this->_getService()->getStreetPartialSearchText($searchData, $buildingNum);
220
+ $searchRequest = $this->_getMethods()->createSearchRequest($data);
221
+ $searchResult = $this->_getService()->searchAction($searchRequest, true, $searchText);
222
+
223
+ if($searchResult['matchType'] === 'Verified' || $searchResult['matchType'] === 'error')
224
+ {
225
+ $this->_getSession()->setInvalidInfo(FALSE);
226
+ $this->_saveAndReturn($data, $searchResult);
227
+ return;
228
+ }
229
+ else if($searchResult['matchType'] === 'StreetPartial')
230
+ {
231
+
232
+ $this->_getSession()->setInvalidInfo(TRUE);
233
+ $this->_getSession()->setCustomerData($data);
234
+ $this->loadLayout()->renderLayout();
235
+ return;
236
+ }
237
+ else
238
+ {
239
+
240
+ $this->_getSession()->setInvalidInfo(TRUE);
241
+ $this->_getSession()->setCustomerData($data);
242
+ $this->_getSession()->setSearchResult($searchResult);
243
+ $this->loadLayout()->renderLayout();
244
+ return;
245
+ }
246
+ }
247
+
248
+ public function refineAction()
249
+ {
250
+ $data = $this->_getSession()->getCustomerData();
251
+ $moniker = $this->getRequest()->getParam('moniker');
252
+
253
+ $refineRequest = new RefineRequest();
254
+ $refineRequest->DataSet = $data['address']['country_id'];
255
+ $refineRequest->Moniker = $moniker;
256
+
257
+ $searchResult = $this->_getService()->refine($refineRequest);
258
+
259
+ if($searchResult['matchType'] === 'Verified' || $searchResult['matchType'] === 'error')
260
+ {
261
+ $this->_getSession()->setInvalidInfo(FALSE);
262
+ $this->_saveAndReturn($data, $searchResult);
263
+ }
264
+ else
265
+ {
266
+ $this->_getSession()->setInvalidInfo(TRUE);
267
+ $this->_getSession()->setCustomerData($data);
268
+ $this->_getSession()->setSearchResult($searchResult);
269
+ $this->loadLayout()->renderLayout();
270
+ return;
271
+ }
272
+ }
273
+
274
+ public function formatAction()
275
+ {
276
+ $data = $this->_getSession()->getCustomerData();
277
+ $moniker = $this->getRequest()->getParam('moniker');
278
+
279
+ $getAddressRequest = new GetAddressRequest();
280
+ $getAddressRequest->DataSet = $data['address']['country_id'];
281
+ $getAddressRequest->Moniker = $moniker;
282
+
283
+ $searchResult = $this->_getService()->getAddress($getAddressRequest);
284
+
285
+ $this->_saveAndReturn($data, $searchResult);
286
+ }
287
+
288
+ public function aptAddAction()
289
+ {
290
+ $searchResult = $this->_getSession()->getSearchResult();
291
+ $aptNo = $this->getRequest()->getParam('refinetext');
292
+
293
+ $aptIndex = 0;
294
+ $aptLine = false;
295
+ $size = count($searchResult['cleanAddress']);
296
+ while(!$aptLine && $aptIndex < $size)
297
+ {
298
+ if(preg_match("/^\d+\s/", $searchResult['cleanAddress'][$aptIndex]))
299
+ {
300
+ $aptLine = true;
301
+ $searchResult['cleanAddress'][$aptIndex] = $aptNo . "-" . $searchResult['cleanAddress'][$aptIndex];
302
+ }
303
+ $aptIndex++;
304
+ }
305
+ $this->_saveAndReturn(
306
+ $this->_getSession()->getCustomerData(),
307
+ $searchResult);
308
+ }
309
+
310
+ public function originalAction()
311
+ {
312
+ $this->_saveAndReturn($this->_getSession()->getCustomerData());
313
+ }
314
+
315
+ private function _getData($isBilling, $isCheckout)
316
+ {
317
+ $returnData = array();
318
+
319
+ if ($this->getRequest()->isPost())
320
+ {
321
+ if($isCheckout)
322
+ {
323
+ $key = $isBilling ? 'billing' : 'shipping';
324
+ $addressId = $isBilling ? 'billing_address_id' : 'shipping_address_id';
325
+
326
+ $returnData['address'] = $this->getRequest()->getPost($key, array());
327
+ $returnData['customerAddressId'] = $this->getRequest()->getPost($addressId, false);
328
+
329
+ if(!empty($returnData['customerAddressId']))
330
+ {
331
+ $returnData['address'] = $this->_getMethods()->getRegisteredAddress($returnData['customerAddressId'], count($returnData['address']['street']));
332
+ }
333
+
334
+ if($isBilling && isset($returnData['address']['email']))
335
+ {
336
+ $returnData['address']['email'] = trim($returnData['address']['email']);
337
+ }
338
+
339
+ if($isBilling)
340
+ {
341
+ Mage::getSingleton('checkout/type_onepage')->saveBilling($returnData['address'], $returnData['customerAddressId']);
342
+ }
343
+ else
344
+ {
345
+ Mage::getSingleton('checkout/type_onepage')->saveShipping($returnData['address'], $returnData['customerAddressId']);
346
+ }
347
+ }
348
+ else
349
+ {
350
+ $address = Mage::getModel('customer/address');
351
+ $addressForm = Mage::getModel('customer/form');
352
+ $addressForm->setFormCode('customer_address_edit')->setEntity($address);
353
+ $returnData['address'] = $addressForm->extractData($this->getRequest());
354
+ }
355
+ }
356
+
357
+ return $returnData;
358
+ }
359
+
360
+ private function _saveAndReturn($data, $searchResult = null)
361
+ {
362
+ $isCheckOut = $this->_getSession()->getIsCheckout();
363
+
364
+ $edqInfo = $this->_getMethods()->createEdqInfo($searchResult, $data);
365
+ $this->_getSession()->setEdqInfo($edqInfo);
366
+
367
+ if($edqInfo['matchType'] === 'error')
368
+ {
369
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($edqInfo));
370
+ return;
371
+ }
372
+
373
+ if($isCheckOut)
374
+ {
375
+ if(($data['address']['country_id'] === 'US' && $this->_getSettings()->areUSDataSetsEnabled())
376
+ || ($data['address']['country_id'] === 'CA' && $this->_getSettings()->isCANEnabled()))
377
+ {
378
+ $this->_getService()->insertIntoDataBase();
379
+ }
380
+ }
381
+
382
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($data));
383
+ }
384
+
385
+ private function _getService()
386
+ {
387
+ return Mage::getModel('addressvalidation/Service');
388
+ }
389
+
390
+ private function _getSettings()
391
+ {
392
+ return Mage::helper('addressvalidation/Settings');
393
+ }
394
+
395
+ private function _getMethods()
396
+ {
397
+ return Mage::helper('addressvalidation/Methods');
398
+ }
399
+
400
+ private function _getSession()
401
+ {
402
+ return Mage::getSingleton('core/session');
403
+ }
404
+
405
+ private function _getTranslation($text)
406
+ {
407
+ return Mage::getSingleton('core/translate')->translate(array($text));
408
+ }
409
+ }
app/code/community/EDQ/AddressValidation/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <experiandataquality_addressvalidation module="addressvalidation">
12
+ <title>Experian Data Quality</title>
13
+ </experiandataquality_addressvalidation>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/EDQ/AddressValidation/etc/config.xml ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <config>
3
+ <modules>
4
+ <EDQ_AddressValidation>
5
+ <version>1.0.5</version>
6
+ </EDQ_AddressValidation>
7
+ </modules>
8
+ <global>
9
+ <resources>
10
+ <addressvalidation_setup>
11
+ <setup>
12
+ <module>EDQ_AddressValidation</module>
13
+ </setup>
14
+ </addressvalidation_setup>
15
+ </resources>
16
+ <helpers>
17
+ <addressvalidation>
18
+ <class>EDQ_AddressValidation_Helper</class>
19
+ </addressvalidation>
20
+ </helpers>
21
+ <models>
22
+ <addressvalidation>
23
+ <class>EDQ_AddressValidation_Model</class>
24
+ <resourceModel>addressvalidation_resource</resourceModel>
25
+ </addressvalidation>
26
+ <addressvalidation_resource>
27
+ <class>EDQ_AddressValidation_Model_Resource</class>
28
+ <entities>
29
+ <customer>
30
+ <table>addressvalidation_customer</table>
31
+ </customer>
32
+ <quote>
33
+ <table>addressvalidation_quote</table>
34
+ </quote>
35
+ </entities>
36
+ </addressvalidation_resource>
37
+ </models>
38
+ <events>
39
+ <adminhtml_init_system_config>
40
+ <observers>
41
+ <EDQ_AddressValidation>
42
+ <type>singleton</type>
43
+ <class>addressvalidation/observer</class>
44
+ <method>adminhtmlBlockSystemConfigInitTabSectionsBefore</method>
45
+ </EDQ_AddressValidation>
46
+ </observers>
47
+ </adminhtml_init_system_config>
48
+ <customer_address_save_after>
49
+ <observers>
50
+ <EDQ_AddressValidation>
51
+ <type>singleton</type>
52
+ <class>addressvalidation/observer</class>
53
+ <method>customerAddressSaveAfter</method>
54
+ </EDQ_AddressValidation>
55
+ </observers>
56
+ </customer_address_save_after>
57
+ </events>
58
+ </global>
59
+ <adminhtml>
60
+ <layout>
61
+ <updates>
62
+ <addressvalidation module="EDQ_AddressValidation">
63
+ <file>edqaddressvalidation.xml</file>
64
+ </addressvalidation>
65
+ </updates>
66
+ </layout>
67
+ <translate>
68
+ <modules>
69
+ <EDQ_AddressValidation>
70
+ <files>
71
+ <default>EDQ_AddressValidation.csv</default>
72
+ </files>
73
+ </EDQ_AddressValidation>
74
+ </modules>
75
+ </translate>
76
+ </adminhtml>
77
+ <admin>
78
+ <routers>
79
+ <adminhtml>
80
+ <args>
81
+ <use>admin</use>
82
+ <modules>
83
+ <EDQ_AddressValidation before="Mage_Adminhtml">EDQ_AddressValidation</EDQ_AddressValidation>
84
+ <frontName>admin</frontName>
85
+ </modules>
86
+ </args>
87
+ </adminhtml>
88
+ </routers>
89
+ </admin>
90
+ <frontend>
91
+ <routers>
92
+ <customer>
93
+ <args>
94
+ <modules>
95
+ <EDQ_AddressValidation before='Mage_Customer'>EDQ_AddressValidation</EDQ_AddressValidation>
96
+ </modules>
97
+ </args>
98
+ </customer>
99
+ <checkout>
100
+ <args>
101
+ <modules>
102
+ <EDQ_AddressValidation before='Mage_Checkout'>EDQ_AddressValidation</EDQ_AddressValidation>
103
+ </modules>
104
+ </args>
105
+ </checkout>
106
+ </routers>
107
+ <translate>
108
+ <modules>
109
+ <EDQ_AddressValidation>
110
+ <files>
111
+ <default>EDQ_AddressValidation.csv</default>
112
+ </files>
113
+ </EDQ_AddressValidation>
114
+ </modules>
115
+ </translate>
116
+ <layout>
117
+ <updates>
118
+ <addressvalidation module="EDQ_AddressValidation">
119
+ <file>edqaddressvalidation.xml</file>
120
+ </addressvalidation>
121
+ </updates>
122
+ </layout>
123
+ </frontend>
124
+ <default>
125
+ <experiandataquality_addressvalidation>
126
+ <settings>
127
+ <service_type><![CDATA[proondemand]]></service_type>
128
+ <endpoint><![CDATA[https://ws2.ondemand.qas.com/ProOnDemand/V3/ProOnDemandService.asmx]]></endpoint>
129
+ <enable_ati><![CDATA[0]]></enable_ati>
130
+ <usa_clean><![CDATA[0]]></usa_clean>
131
+ <usa_layout><![CDATA[USA2 TitleCase Retention DPV]]></usa_layout>
132
+ <use_layout><![CDATA[USE2 AptLine2 TitleCase Retention]]></use_layout>
133
+ <can_clean><![CDATA[0]]></can_clean>
134
+ <can_layout><![CDATA[CAN2 TitleCase Retention LVR]]></can_layout>
135
+ <gbr_clean><![CDATA[0]]></gbr_clean>
136
+ <gbr_layout><![CDATA[QADefault]]></gbr_layout>
137
+ <deu_clean><![CDATA[0]]></deu_clean>
138
+ <deu_layout><![CDATA[MegentoDEU]]></deu_layout>
139
+ <irl_clean><![CDATA[0]]></irl_clean>
140
+ <irl_layout><![CDATA[MagentoIRL]]></irl_layout>
141
+ <use_proxy><![CDATA[0]]></use_proxy>
142
+ <user_interaction><![CDATA[1]]></user_interaction>
143
+ <manual_address_entry><![CDATA[0]]></manual_address_entry>
144
+ <lvr><![CDATA[6]]></lvr>
145
+ <ir_disp><![CDATA[5]]></ir_disp>
146
+ </settings>
147
+ </experiandataquality_addressvalidation>
148
+ </default>
149
+ </config>
app/code/community/EDQ/AddressValidation/etc/system.xml ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <config>
3
+ <sections>
4
+ <experiandataquality_addressvalidation translate="label" module="addressvalidation">
5
+ <label>Address</label>
6
+ <sort_order>20</sort_order>
7
+ <tab>experiandataquality</tab>
8
+ <show_in_default>1</show_in_default>
9
+ <show_in_website>1</show_in_website>
10
+ <show_in_store>1</show_in_store>
11
+ <groups>
12
+ <settings translate="label" module="addressvalidation">
13
+ <label>Address Validation Settings</label>
14
+ <sort_order>10</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <fields>
19
+ <service_type translate="label" module="addressvalidation">
20
+ <backend_model>addressvalidation/validate</backend_model>
21
+ <label>Service</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>EDQ_AddressValidation_Model_ServiceProviders</source_model>
24
+ <sort_order>10</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </service_type>
29
+ <!--
30
+ Pro OnDemand Settings
31
+ -->
32
+ <proondemand_heading translate="label">
33
+ <label>Pro On Demand Settings</label>
34
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
35
+ <sort_order>40</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ <depends><service_type><![CDATA[proondemand]]></service_type></depends>
40
+ </proondemand_heading>
41
+ <endpoint translate="label" module="addressvalidation">
42
+ <label>On Demand Endpoint</label>
43
+ <frontend_type>text</frontend_type>
44
+ <sort_order>50</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ <depends><service_type><![CDATA[proondemand]]></service_type></depends>
49
+ </endpoint>
50
+ <token translate="label" module="addressvalidation">
51
+ <label>On Demand Token</label>
52
+ <frontend_type>text</frontend_type>
53
+ <sort_order>60</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ <depends><service_type><![CDATA[proondemand]]></service_type></depends>
58
+ </token>
59
+ <!--
60
+ Pro OnDemand Settings
61
+ -->
62
+ <!--
63
+ USA Settings
64
+ -->
65
+ <usa_heading translate="label">
66
+ <label>USA Dataset Settings</label>
67
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
68
+ <sort_order>80</sort_order>
69
+ <show_in_default>1</show_in_default>
70
+ <show_in_website>1</show_in_website>
71
+ <show_in_store>1</show_in_store>
72
+ </usa_heading>
73
+ <enable_ati translate="label" module="addressvalidation">
74
+ <label>Enable ATI</label>
75
+ <frontend_type>select</frontend_type>
76
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
77
+ <sort_order>90</sort_order>
78
+ <show_in_default>1</show_in_default>
79
+ <show_in_website>1</show_in_website>
80
+ <show_in_store>1</show_in_store>
81
+ </enable_ati>
82
+ <usa_clean translate="label" module="addressvalidation">
83
+ <label>USA Clean</label>
84
+ <frontend_type>select</frontend_type>
85
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
86
+ <sort_order>100</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>1</show_in_store>
90
+ </usa_clean>
91
+ <usa_layout translate="label" module="addressvalidation">
92
+ <label>USA Layout</label>
93
+ <frontend_type>text</frontend_type>
94
+ <sort_order>110</sort_order>
95
+ <show_in_default>1</show_in_default>
96
+ <show_in_website>1</show_in_website>
97
+ <show_in_store>1</show_in_store>
98
+ <depends><usa_clean>1</usa_clean></depends>
99
+ </usa_layout>
100
+ <use_layout translate="label" module="addressvalidation">
101
+ <label>USE Layout</label>
102
+ <frontend_type>text</frontend_type>
103
+ <sort_order>120</sort_order>
104
+ <show_in_default>1</show_in_default>
105
+ <show_in_website>1</show_in_website>
106
+ <show_in_store>1</show_in_store>
107
+ <depends><enable_ati>1</enable_ati></depends>
108
+ </use_layout>
109
+ <!--
110
+ USA Settings
111
+ -->
112
+ <!--
113
+ CAN Settings
114
+ -->
115
+ <can_heading translate="label">
116
+ <label>CAN Dataset Settings</label>
117
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
118
+ <sort_order>130</sort_order>
119
+ <show_in_default>1</show_in_default>
120
+ <show_in_website>1</show_in_website>
121
+ <show_in_store>1</show_in_store>
122
+ </can_heading>
123
+ <can_clean translate="label" module="addressvalidation">
124
+ <label>CAN Clean</label>
125
+ <frontend_type>select</frontend_type>
126
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
127
+ <sort_order>140</sort_order>
128
+ <show_in_default>1</show_in_default>
129
+ <show_in_website>1</show_in_website>
130
+ <show_in_store>1</show_in_store>
131
+ </can_clean>
132
+ <can_layout translate="label" module="addressvalidation">
133
+ <label>CAN Layout</label>
134
+ <frontend_type>text</frontend_type>
135
+ <sort_order>150</sort_order>
136
+ <show_in_default>1</show_in_default>
137
+ <show_in_website>1</show_in_website>
138
+ <show_in_store>1</show_in_store>
139
+ <depends><can_clean>1</can_clean></depends>
140
+ </can_layout>
141
+ <!--
142
+ CAN Settings
143
+ -->
144
+ <!--
145
+ GBR Settings
146
+ -->
147
+ <grb_heading translate="label">
148
+ <label>GBR Dataset Settings</label>
149
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
150
+ <sort_order>160</sort_order>
151
+ <show_in_default>1</show_in_default>
152
+ <show_in_website>1</show_in_website>
153
+ <show_in_store>1</show_in_store>
154
+ </grb_heading>
155
+ <gbr_clean translate="label" module="addressvalidation">
156
+ <label>GBR Clean</label>
157
+ <frontend_type>select</frontend_type>
158
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
159
+ <sort_order>170</sort_order>
160
+ <show_in_default>1</show_in_default>
161
+ <show_in_website>1</show_in_website>
162
+ <show_in_store>1</show_in_store>
163
+ </gbr_clean>
164
+ <gbr_layout translate="label" module="addressvalidation">
165
+ <label>GBR Layout</label>
166
+ <frontend_type>text</frontend_type>
167
+ <sort_order>180</sort_order>
168
+ <show_in_default>1</show_in_default>
169
+ <show_in_website>1</show_in_website>
170
+ <show_in_store>1</show_in_store>
171
+ <depends><gbr_clean>1</gbr_clean></depends>
172
+ </gbr_layout>
173
+ <!--
174
+ GBR Settings
175
+ -->
176
+ <!--
177
+ DEU Settings
178
+ -->
179
+ <deu_heading translate="label">
180
+ <label>DEU Dataset Settings</label>
181
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
182
+ <sort_order>190</sort_order>
183
+ <show_in_default>1</show_in_default>
184
+ <show_in_website>1</show_in_website>
185
+ <show_in_store>1</show_in_store>
186
+ </deu_heading>
187
+ <deu_clean translate="label" module="addressvalidation">
188
+ <label>DEU Clean</label>
189
+ <frontend_type>select</frontend_type>
190
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
191
+ <sort_order>200</sort_order>
192
+ <show_in_default>1</show_in_default>
193
+ <show_in_website>1</show_in_website>
194
+ <show_in_store>1</show_in_store>
195
+ </deu_clean>
196
+ <deu_layout translate="label" module="addressvalidation">
197
+ <label>DEU Layout</label>
198
+ <frontend_type>text</frontend_type>
199
+ <sort_order>210</sort_order>
200
+ <show_in_default>1</show_in_default>
201
+ <show_in_website>1</show_in_website>
202
+ <show_in_store>1</show_in_store>
203
+ <depends><deu_clean>1</deu_clean></depends>
204
+ </deu_layout>
205
+ <!--
206
+ DEU Settings
207
+ -->
208
+ <!--
209
+ IRL Settings
210
+ -->
211
+ <irl_heading translate="label">
212
+ <label>IRL Dataset Settings</label>
213
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
214
+ <sort_order>220</sort_order>
215
+ <show_in_default>1</show_in_default>
216
+ <show_in_website>1</show_in_website>
217
+ <show_in_store>1</show_in_store>
218
+ </irl_heading>
219
+ <irl_clean translate="label" module="addressvalidation">
220
+ <label>IRL Clean</label>
221
+ <frontend_type>select</frontend_type>
222
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
223
+ <sort_order>230</sort_order>
224
+ <show_in_default>1</show_in_default>
225
+ <show_in_website>1</show_in_website>
226
+ <show_in_store>1</show_in_store>
227
+ </irl_clean>
228
+ <irl_layout translate="label" module="addressvalidation">
229
+ <label>IRL Layout</label>
230
+ <frontend_type>text</frontend_type>
231
+ <sort_order>240</sort_order>
232
+ <show_in_default>1</show_in_default>
233
+ <show_in_website>1</show_in_website>
234
+ <show_in_store>1</show_in_store>
235
+ <depends><irl_clean>1</irl_clean></depends>
236
+ </irl_layout>
237
+ <!--
238
+ IRL Settings
239
+ -->
240
+ <!--
241
+ Proxy Settings
242
+ -->
243
+ <proxy_heading translate="label">
244
+ <label>Proxy Server Settings</label>
245
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
246
+ <sort_order>250</sort_order>
247
+ <show_in_default>1</show_in_default>
248
+ <show_in_website>1</show_in_website>
249
+ <show_in_store>1</show_in_store>
250
+ </proxy_heading>
251
+ <use_proxy translate="label" module="addressvalidation">
252
+ <label>Use a proxy</label>
253
+ <frontend_type>select</frontend_type>
254
+ <source_model>adminhtml/system_config_source_yesno</source_model>
255
+ <sort_order>260</sort_order>
256
+ <show_in_default>1</show_in_default>
257
+ <show_in_website>1</show_in_website>
258
+ <show_in_store>1</show_in_store>
259
+ </use_proxy>
260
+ <proxyname translate="label" module="addressvalidation">
261
+ <label>Proxy URL</label>
262
+ <frontend_type>text</frontend_type>
263
+ <sort_order>270</sort_order>
264
+ <show_in_default>1</show_in_default>
265
+ <show_in_website>1</show_in_website>
266
+ <show_in_store>1</show_in_store>
267
+ <depends><use_proxy>1</use_proxy></depends>
268
+ </proxyname>
269
+ <proxyport translate="label" module="addressvalidation">
270
+ <label>Proxy Port</label>
271
+ <frontend_type>text</frontend_type>
272
+ <validate>validate-number</validate>
273
+ <sort_order>280</sort_order>
274
+ <show_in_default>1</show_in_default>
275
+ <show_in_website>1</show_in_website>
276
+ <show_in_store>1</show_in_store>
277
+ <depends><use_proxy>1</use_proxy></depends>
278
+ </proxyport>
279
+ <proxyuser translate="label" module="addressvalidation">
280
+ <label>Proxy Username</label>
281
+ <frontend_type>text</frontend_type>
282
+ <sort_order>290</sort_order>
283
+ <show_in_default>1</show_in_default>
284
+ <show_in_website>1</show_in_website>
285
+ <show_in_store>1</show_in_store>
286
+ <depends><use_proxy>1</use_proxy></depends>
287
+ </proxyuser>
288
+ <proxypassword translate="label" module="addressvalidation">
289
+ <label>Proxy Password</label>
290
+ <frontend_type>text</frontend_type>
291
+ <sort_order>300</sort_order>
292
+ <show_in_default>1</show_in_default>
293
+ <show_in_website>1</show_in_website>
294
+ <show_in_store>1</show_in_store>
295
+ <depends><use_proxy>1</use_proxy></depends>
296
+ </proxypassword>
297
+ <!--
298
+ Proxy Settings
299
+ -->
300
+
301
+ <!--
302
+ Additional Settings
303
+ -->
304
+ <additional_configss_heading translate="label">
305
+ <label>Additional Settings</label>
306
+ <frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
307
+ <sort_order>310</sort_order>
308
+ <show_in_default>1</show_in_default>
309
+ <show_in_website>1</show_in_website>
310
+ <show_in_store>1</show_in_store>
311
+ </additional_configss_heading>
312
+ <user_interaction translate="label" module="addressvalidation">
313
+ <label>Prompt for User Interaction</label>
314
+ <frontend_type>select</frontend_type>
315
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
316
+ <sort_order>320</sort_order>
317
+ <show_in_default>1</show_in_default>
318
+ <show_in_website>1</show_in_website>
319
+ <show_in_store>1</show_in_store>
320
+ </user_interaction>
321
+ <manual_address_entry translate="label" module="addressvalidation">
322
+ <label>Manual Address Entry</label>
323
+ <frontend_type>select</frontend_type>
324
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
325
+ <sort_order>330</sort_order>
326
+ <show_in_default>1</show_in_default>
327
+ <show_in_website>1</show_in_website>
328
+ <show_in_store>1</show_in_store>
329
+ </manual_address_entry>
330
+ <lvr translate="label" module="addressvalidation">
331
+ <label>LVR Check Line Number</label>
332
+ <frontend_type>text</frontend_type>
333
+ <validate>validate-number</validate>
334
+ <sort_order>340</sort_order>
335
+ <show_in_default>1</show_in_default>
336
+ <show_in_website>1</show_in_website>
337
+ <show_in_store>1</show_in_store>
338
+ </lvr>
339
+ <ir_disp translate="label" module="addressvalidation">
340
+ <label>Interaction Required Display Lines</label>
341
+ <frontend_type>text</frontend_type>
342
+ <validate>validate-number</validate>
343
+ <sort_order>350 </sort_order>
344
+ <show_in_default>1</show_in_default>
345
+ <show_in_website>1</show_in_website>
346
+ <show_in_store>1</show_in_store>
347
+ </ir_disp>
348
+ <!--
349
+ Additional Settings
350
+ -->
351
+ </fields>
352
+ </settings>
353
+ </groups>
354
+ </experiandataquality_addressvalidation>
355
+ </sections>
356
+ </config>
app/code/community/EDQ/AddressValidation/sql/addressvalidation_setup/install-1.0.5.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Mage_Core_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $addressValidationCustomerTable = $installer->getConnection()
8
+ ->newTable($installer->getTable('addressvalidation/customer'))
9
+ ->addColumn('customer_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 10,
10
+ array(
11
+ 'auto_increment' => true,
12
+ 'indentify' => true,
13
+ 'unsigned' => true,
14
+ 'nullable' => false,
15
+ 'primary' => true
16
+ ), 'Id')
17
+ ->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 10,
18
+ array(
19
+ 'nullable' => false,
20
+ 'unsigned' => true,
21
+ 'default' => '0'
22
+ ), 'Entity Id')
23
+ ->addColumn('matchtype', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255,
24
+ array(
25
+ 'nullable' => true,
26
+ 'default' => null
27
+ ), 'MatchType')
28
+ ->addColumn('additionaldata', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255,
29
+ array(
30
+ 'nullable' => true,
31
+ 'default' => null
32
+ ), 'Additional Data')
33
+ ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null,
34
+ array(
35
+ 'nullable' => true,
36
+ 'default' => null
37
+ ), 'Timestamp')
38
+
39
+ ->addIndex($installer->getIdxName('addressvalidation/customer', array('timestamp')), array('timestamp'), array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX))
40
+ ->addForeignKey('FK_ADDRESSVALIADTION_CUSTOMER', 'entity_id', $installer->getTable('customer_address_entity'), 'entity_id',
41
+ Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
42
+ ->setOption('type', 'INNODB')
43
+ ->setOption('charset', 'utf8');
44
+
45
+ $installer->getConnection()->createTable($addressValidationCustomerTable);
46
+
47
+ $addressValidationQuoteTable = $installer->getConnection()
48
+ ->newTable($installer->getTable('addressvalidation/quote'))
49
+ ->addColumn('quote_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 10,
50
+ array(
51
+ 'auto_increment' => true,
52
+ 'indentify' => true,
53
+ 'unsigned' => true,
54
+ 'nullable' => false,
55
+ 'primary' => true
56
+ ), 'Id')
57
+ ->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 10,
58
+ array(
59
+ 'nullable' => false,
60
+ 'unsigned' => true,
61
+ 'default' => '0'
62
+ ), 'Entity Id')
63
+ ->addColumn('address_type', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255,
64
+ array(
65
+ 'nullable' => true,
66
+ 'default' => null
67
+ ), 'Address Type')
68
+ ->addColumn('matchtype', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255,
69
+ array(
70
+ 'nullable' => true,
71
+ 'default' => null
72
+ ), 'MatchType')
73
+ ->addColumn('additionaldata', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255,
74
+ array(
75
+ 'nullable' => true,
76
+ 'default' => null
77
+ ), 'Additional Data')
78
+ ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null,
79
+ array(
80
+ 'nullable' => true,
81
+ 'default' => null
82
+ ), 'Timestamp')
83
+ ->addIndex($installer->getIdxName('addressvalidation/quote', array('timestamp')), array('timestamp'), array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX))
84
+ ->addForeignKey('FK_ADDRESSVALIADTION_QUOTE', 'entity_id', $installer->getTable('sales_flat_quote'), 'entity_id',
85
+ Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
86
+ ->setOption('type', 'INNODB')
87
+ ->setOption('charset', 'utf8');
88
+
89
+ $installer->getConnection()->createTable($addressValidationQuoteTable);
90
+
91
+ $installer->endSetup();
app/code/community/EDQ/EmailAndPhoneValidation/Helper/Data.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ /**
5
+ * Config path to enable email validation
6
+ */
7
+ const XML_PATH_EMAIL_VALIDATION_ENABLED = 'experiandataquality_emailandphonevalidation/settings/enable_email_validate';
8
+ /**
9
+ * Config path to email service url
10
+ */
11
+ const XML_PATH_EMAIL_SERVICE_URL = 'experiandataquality_emailandphonevalidation/settings/email_service_url';
12
+ /**
13
+ * Config path for email validation key
14
+ */
15
+ const XML_PATH_EMAIL_VALIDATION_TOKEN = 'experiandataquality_emailandphonevalidation/settings/email_validation_token';
16
+ /**
17
+ * Config path to enable phone validation
18
+ */
19
+ const XML_PATH_PHONE_VALIDATION_ENABLED = 'experiandataquality_emailandphonevalidation/settings/enable_phone_validate';
20
+ /**
21
+ * Config path to phone service url
22
+ */
23
+ const XML_PATH_PHONE_SERVICE_URL = 'experiandataquality_emailandphonevalidation/settings/phone_service_url';
24
+ /**
25
+ * Config path for phone validation key
26
+ */
27
+ const XML_PATH_PHONE_VALIDATION_TOKEN = 'experiandataquality_emailandphonevalidation/settings/phone_validation_token';
28
+ /**
29
+ * Config path to phone default country
30
+ */
31
+ const XML_PATH_PHONE_DEFAULT_COUNTRY = 'experiandataquality_emailandphonevalidation/settings/phone_default_country';
32
+ /**
33
+ * Config path to enable select country options
34
+ */
35
+ const XML_PATH_PHONE_COUNTRY_SELECTION_ENABLED = 'experiandataquality_emailandphonevalidation/settings/use_phone_country_selection';
36
+ /**
37
+ * Config path for session token live time in minutes
38
+ */
39
+ const XML_PATH_ENABLE_SESSION_TOKEN_SECURITY = 'experiandataquality_emailandphonevalidation/security/enable_session_token_security';
40
+ /**
41
+ * Config path for session token live time in minutes
42
+ */
43
+ const XML_PATH_SESSION_TOKEN_LIVE_TIME = 'experiandataquality_emailandphonevalidation/security/session_token_life_time_in_minutes';
44
+
45
+ /**
46
+ * Check if Email Validate is enabled
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function isEmailValidateEnabled()
51
+ {
52
+ return (bool)Mage::getStoreConfig(self::XML_PATH_EMAIL_VALIDATION_ENABLED);
53
+ }
54
+
55
+ /**
56
+ * Check if Phone Validate is enabled
57
+ *
58
+ * @return boolean
59
+ */
60
+ public function isPhoneValidateEnabled()
61
+ {
62
+ return (bool)Mage::getStoreConfig(self::XML_PATH_PHONE_VALIDATION_ENABLED);
63
+ }
64
+
65
+ /**
66
+ * Retrieve Email Validation key
67
+ *
68
+ * @return string
69
+ */
70
+ public function getEmailValidateKey()
71
+ {
72
+ return Mage::getStoreConfig(self::XML_PATH_EMAIL_VALIDATION_TOKEN);
73
+ }
74
+
75
+ /**
76
+ * Retrieve Phone Validation key
77
+ *
78
+ * @return string
79
+ */
80
+ public function getPhoneValidateKey()
81
+ {
82
+ return Mage::getStoreConfig(self::XML_PATH_PHONE_VALIDATION_TOKEN);
83
+ }
84
+
85
+ /**
86
+ * Retrieve Email Service Url
87
+ *
88
+ * @return string
89
+ */
90
+ public function getEmailServiceUrl()
91
+ {
92
+ return Mage::getStoreConfig(self::XML_PATH_EMAIL_SERVICE_URL);
93
+ }
94
+
95
+ /**
96
+ * Retrieve Phone Service Url
97
+ *
98
+ * @return string
99
+ */
100
+ public function getPhoneServiceUrl()
101
+ {
102
+ return Mage::getStoreConfig(self::XML_PATH_PHONE_SERVICE_URL);
103
+ }
104
+
105
+ /**
106
+ * Check if Session Security is enabled
107
+ *
108
+ * @return boolean
109
+ */
110
+ public function isSessionSecurityEnabled()
111
+ {
112
+ return (bool)Mage::getStoreConfig(self::XML_PATH_ENABLE_SESSION_TOKEN_SECURITY);
113
+ }
114
+
115
+ /**
116
+ * Check if Phone Country Selection is enabled
117
+ *
118
+ * @return boolean
119
+ */
120
+ public function isPhoneCountrySelectionEnabled()
121
+ {
122
+ return (bool)Mage::getStoreConfig(self::XML_PATH_PHONE_COUNTRY_SELECTION_ENABLED);
123
+ }
124
+
125
+ /**
126
+ * Retrieve Phone Default Country
127
+ *
128
+ * @return string
129
+ */
130
+ public function getPhoneDefaultCountry()
131
+ {
132
+ return Mage::getStoreConfig(self::XML_PATH_PHONE_DEFAULT_COUNTRY);
133
+ }
134
+
135
+ /**
136
+ * Retrieve Token Life Time
137
+ *
138
+ * @return string
139
+ */
140
+ public function getSessionSecurityTokenLifeTime()
141
+ {
142
+ return Mage::getStoreConfig(self::XML_PATH_SESSION_TOKEN_LIVE_TIME);
143
+ }
144
+ /**
145
+ * Returns current date and time based on Magento time zone
146
+ *
147
+ *@return date
148
+ */
149
+ public function getCurrentDateTime()
150
+ {
151
+ $currentTimestamp = Mage::getModel('core/date')->timestamp(time());
152
+ $date = date('Y-m-d H:i:s', $currentTimestamp);
153
+ return $date;
154
+ }
155
+
156
+ /**
157
+ * Check if string is null or empty
158
+ *
159
+ *@return bool
160
+ */
161
+ public function isNullOrEmptyString($string)
162
+ {
163
+ return (!isset($string) || trim($string)==='');
164
+ }
165
+
166
+ /**
167
+ * Check if string is null or it contains only white spaces
168
+ *
169
+ *@return bool
170
+ */
171
+ public function isNullOrWhiteSpace($string)
172
+ {
173
+ return ($this->isNullOrEmptyString($string) || strlen(trim($string)) == 0);
174
+ }
175
+
176
+ /**
177
+ * Check if heystack begins with begins with needle
178
+ *
179
+ *@return bool
180
+ */
181
+ public function startsWith($needle, $haystack)
182
+ {
183
+ $beginingToCompare = substr($haystack, 0, strlen($needle));
184
+ return (strcmp($beginingToCompare, $needle) == 0);
185
+ }
186
+
187
+ /**
188
+ * Returns DataSet based on country code
189
+ *
190
+ *@return string
191
+ */
192
+ public function getDataSetByCountryCode($code)
193
+ {
194
+ switch ($code)
195
+ {
196
+ case "+1":
197
+ return 'USA';
198
+ case "+44":
199
+ return 'GBR';
200
+ case "+61":
201
+ return 'AUS';
202
+ case "+33":
203
+ return 'FRA';
204
+ default:
205
+ return false;
206
+ }
207
+ }
208
+ }
app/code/community/EDQ/EmailAndPhoneValidation/Model/Observer.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Model_Observer
3
+ {
4
+ public function addExperianModuleTab(Varien_Event_Observer $observer)
5
+ {
6
+ //get init sections and tabs
7
+ $config = $observer->getConfig();
8
+
9
+ //get tab 'experiandataquality'
10
+ $experianDataQualityTab = $config->getNode('tabs/experiandataquality');
11
+
12
+ if(!$experianDataQualityTab)
13
+ {
14
+ $new_tab_xml = new Mage_Core_Model_Config_Element('
15
+ <experiandataquality>
16
+ <label>Experian Data Quality</label>
17
+ <sort_order>10</sort_order>
18
+ </experiandataquality>
19
+ ');
20
+
21
+ $tabs = $config->getNode('tabs');
22
+ $tabs->appendChild($new_tab_xml);
23
+ }
24
+
25
+ return $this;
26
+ }
27
+ }
app/code/community/EDQ/EmailAndPhoneValidation/Model/Phone/PhoneFormater.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Model_Phone_PhoneFormater
3
+ {
4
+ public function formatInput($phoneNumber, $countryCode)
5
+ {
6
+ $helper = Mage::helper('edq_emailandphonevalidation');
7
+
8
+ if ($helper->isNullOrWhiteSpace($phoneNumber))
9
+ {
10
+ throw new Exception('Phone number is empty');
11
+ }
12
+
13
+ if($helper->isNullOrEmptyString($countryCode))
14
+ {
15
+ throw new Exception('Country code is empty');
16
+ }
17
+
18
+ $sanitizedPhone = $this->_sanitizePhoneNumber($phoneNumber);
19
+
20
+ //For Australia and France Neustar is used the country code needs to be prepended to the phone number.
21
+ //This is per an email from Jignesh Patel sent to Kos on 12.05.2014
22
+ if(strcmp($countryCode, '+33') == 0 || strcmp($countryCode, '+61') == 0) //France and Australia
23
+ {
24
+ if(!$helper->startsWith($countryCode, $sanitizedPhone))
25
+ {
26
+ if($helper->startsWith('0', $sanitizedPhone)) {
27
+ $sanitizedPhone = substr($sanitizedPhone, 1);
28
+ }
29
+
30
+ $sanitizedPhone = $countryCode . str_replace('+', '', $sanitizedPhone);
31
+ }
32
+ }
33
+
34
+ return $sanitizedPhone;
35
+ }
36
+
37
+ public function formatOutput($response, $originalPhoneInput, $countryCode)
38
+ {
39
+ $helper = Mage::helper('edq_emailandphonevalidation');
40
+
41
+ $phoneResponse = json_decode($response, true);
42
+
43
+ if(strcmp($phoneResponse["Certainty"], 'Unverified') == 0)
44
+ {
45
+ $phoneResponse["Number"] = $originalPhoneInput;
46
+ }
47
+ else
48
+ {
49
+ $additionalPhoneinfo = !array_key_exists('AdditionalPhoneInfo', $phoneResponse) ? '' : $phoneResponse["AdditionalPhoneInfo"];
50
+
51
+ if(is_array($additionalPhoneinfo) && array_key_exists('ValidatedPhoneNumber', $additionalPhoneinfo))
52
+ {
53
+ $phoneNumber = $additionalPhoneinfo['ValidatedPhoneNumber'];
54
+ }
55
+ else
56
+ {
57
+ $phoneNumber = $phoneResponse["Number"];
58
+ }
59
+
60
+ switch ($countryCode)
61
+ {
62
+ case "+44":
63
+ $phoneNumber = $this->_formatGBRPhoneNumber($phoneNumber);
64
+ break;
65
+ case "+61":
66
+ $phoneNumber = $this->_formatAUSPhoneNumber($phoneNumber);
67
+ break;
68
+ case "+33":
69
+ $phoneNumber = $this->_formatFRAPhoneNumber($phoneNumber);
70
+ break;
71
+ case "+1":
72
+ $phoneNumber = $this->_formatUSAPhoneNumber($phoneNumber);
73
+ break;
74
+ }
75
+
76
+ $phoneResponse["Number"] = $phoneNumber;
77
+ }
78
+
79
+ return $phoneResponse;
80
+ }
81
+
82
+ private function _sanitizePhoneNumber($phoneNumber)
83
+ {
84
+ $helper = Mage::helper('edq_emailandphonevalidation');
85
+ $sanitizedPhone = preg_replace('/[^\d.]/', '', $phoneNumber);
86
+
87
+ if($helper->startsWith('+', $phoneNumber))
88
+ {
89
+ $sanitizedPhone = '+' . $sanitizedPhone;
90
+ }
91
+ else if($helper->startsWith('00', $phoneNumber))
92
+ {
93
+ $sanitizedPhone = '+' . substr($sanitizedPhone, 2);
94
+ }
95
+
96
+ return $sanitizedPhone;
97
+ }
98
+
99
+ private function _formatGBRPhoneNumber($number)
100
+ {
101
+ $formatedNumber = '+';
102
+ $formatedNumber .= substr($number, 0, 2);
103
+ $formatedNumber .= ' ';
104
+ $formatedNumber .= substr($number, 2, 4);
105
+ $formatedNumber .= ' ';
106
+ $formatedNumber .= substr($number, 6, 3);
107
+ $formatedNumber .= ' ';
108
+ $formatedNumber .= substr($number, 9, strlen($number) - 9);
109
+
110
+ return $formatedNumber;
111
+ }
112
+
113
+ private function _formatAUSPhoneNumber($number) {
114
+ $formatedNumber = '+';
115
+ $formatedNumber .= substr($number, 0, 2);
116
+ $formatedNumber .= ' ';
117
+ $formatedNumber .= '(';
118
+ $formatedNumber .= substr($number, 2, 4);
119
+ $formatedNumber .= ')';
120
+ $formatedNumber .= ' ';
121
+ $formatedNumber .= substr($number, 6, 3);
122
+ $formatedNumber .= ' ';
123
+ $formatedNumber .= substr($number, 9, strlen($number) - 9);
124
+
125
+ return $formatedNumber;
126
+ }
127
+
128
+ private function _formatFRAPhoneNumber($number)
129
+ {
130
+ $formatedNumber = '+';
131
+ $formatedNumber .= substr($number, 0, 2);
132
+ $formatedNumber .= ' ';
133
+ $formatedNumber .= substr($number, 2, 1);
134
+ $formatedNumber .= ' ';
135
+ $formatedNumber .= substr($number, 3, 2);
136
+ $formatedNumber .= ' ';
137
+ $formatedNumber .= substr($number, 5, 2);
138
+ $formatedNumber .= ' ';
139
+ $formatedNumber .= substr($number, 7, 2);
140
+ $formatedNumber .= ' ';
141
+ $formatedNumber .= substr($number, 9, strlen($number) - 9);
142
+
143
+ return $formatedNumber;
144
+ }
145
+
146
+ private function _formatUSAPhoneNumber($number) {
147
+ $helper = Mage::helper('edq_emailandphonevalidation');
148
+
149
+ $formatedNumber = '';
150
+ if(strlen($number) > 8 && $helper->startsWith('+', $number))
151
+ {
152
+ $formatedNumber .= substr($number, 0, 2);
153
+ $formatedNumber .= '-';
154
+ $formatedNumber .= substr($number, 2, 3);
155
+ $formatedNumber .= '-';
156
+ $formatedNumber .= substr($number, 5, 3);
157
+ $formatedNumber .= '-';
158
+ $formatedNumber .= substr($number, 8);
159
+ }
160
+ else
161
+ {
162
+ $formatedNumber .= '(';
163
+ $formatedNumber .= substr($number, 0, 3);
164
+ $formatedNumber .= ')';
165
+ $formatedNumber .= ' ';
166
+ $formatedNumber .= substr($number, 3, 3);
167
+ $formatedNumber .= '-';
168
+ $formatedNumber .= substr($number, 6);
169
+ }
170
+
171
+ return $formatedNumber;
172
+ }
173
+ }
app/code/community/EDQ/EmailAndPhoneValidation/Model/SupportedCountries.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Model_System_Config_Source_SupportedCountry
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value'=>'' , 'label'=> Mage::helper('adminhtml')->__('NONE')),
13
+ array('value'=>'+1' , 'label'=> Mage::helper('adminhtml')->__('USA')),
14
+ array('value'=>'+44', 'label'=> Mage::helper('adminhtml')->__('GBR')),
15
+ array('value'=>'+61', 'label'=> Mage::helper('adminhtml')->__('AUS')),
16
+ array('value'=>'+33', 'label'=> Mage::helper('adminhtml')->__('FRA'))
17
+ );
18
+ }
19
+ }
20
+
app/code/community/EDQ/EmailAndPhoneValidation/Model/System/Config/Source/Countries.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Model_System_Config_Source_Countries
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value'=>'+1' , 'label'=> Mage::helper('adminhtml')->__('USA')),
13
+ array('value'=>'+44', 'label'=> Mage::helper('adminhtml')->__('GBR')),
14
+ array('value'=>'+61', 'label'=> Mage::helper('adminhtml')->__('AUS')),
15
+ array('value'=>'+33', 'label'=> Mage::helper('adminhtml')->__('FRA'))
16
+ );
17
+ }
18
+ }
app/code/community/EDQ/EmailAndPhoneValidation/Model/Validate.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EDQ_EmailAndPhoneValidation_Model_Validate extends Mage_Core_Model_Config_Data
3
+ {
4
+ public function _afterSave()
5
+ {
6
+ $moduleName = 'EDQ_EmailAndPhoneValidation';
7
+
8
+ if(!Mage::helper('core')->isModuleOutputEnabled($moduleName)){
9
+ return parent::_afterSave();
10
+ }
11
+
12
+ $data = array(
13
+ "enable_email_validate" => $this->getFieldsetDataValue('enable_email_validate'),
14
+ "email_validation_token" => $this->getFieldsetDataValue('email_validation_token'),
15
+ "email_service_url" => $this->getFieldsetDataValue('email_service_url'),
16
+ "enable_phone_validate" => $this->getFieldsetDataValue('enable_phone_validate'),
17
+ "phone_service_url" => $this->getFieldsetDataValue('phone_service_url'),
18
+ "phone_validation_token" => $this->getFieldsetDataValue('phone_validation_token'),
19
+ "enable_session_token_security" => $this->getGroupSectionFiedSetDataValue('security', 'enable_session_token_security'),
20
+ "session_token_life_time_in_minutes" => $this->getGroupSectionFiedSetDataValue('security', 'session_token_life_time_in_minutes')
21
+ );
22
+
23
+ if($data['enable_email_validate'] == 0 && $data['enable_phone_validate'] == 0 && $data['enable_session_token_security'] == 0) {
24
+ return parent::_afterSave();
25
+ }
26
+
27
+ if($this->_areChangesMade($data)) {
28
+ $errors = array();
29
+ $validationResult = $this->_validateEDQFields($data, $errors);
30
+
31
+ if($validationResult == false)
32
+ {
33
+ for($i=0; $i<count($errors); $i++)
34
+ {
35
+ Mage::getSingleton('core/session')->addError($errors[$i]);
36
+ }
37
+ Mage::throwException('The configuration has not been saved.');
38
+ }
39
+ }
40
+ return parent::_afterSave();
41
+ }
42
+
43
+ private function getGroupSectionFiedSetDataValue($section, $key) {
44
+ if(!$this->hasData('groups')) {
45
+ return '';
46
+ }
47
+
48
+ $groupData = $this->getData('groups');
49
+
50
+ if(array_key_exists($section, $groupData)) {
51
+ if(array_key_exists('fields', (array)$groupData[$section])) {
52
+
53
+ $fields = (array)$groupData[$section]['fields'];
54
+ if(array_key_exists($key, $fields)) {
55
+ return $fields[$key]['value'];
56
+ }
57
+ }
58
+ }
59
+
60
+ return '';
61
+ }
62
+
63
+ private function _areChangesMade($data) {
64
+ $helper = Mage::helper('edq_emailandphonevalidation');
65
+ $areAnyChangesMade = true;
66
+
67
+ if((bool) $data['enable_email_validate'] == $helper->isEmailValidateEnabled()
68
+ && (bool) $data['enable_phone_validate'] == $helper->isPhoneValidateEnabled()
69
+ && (bool) $data['enable_session_token_secuiry'] == $helper->isSessionSecurityEnabled()
70
+ && strcmp($data['email_validation_token'], $helper->getEmailValidateKey()) == 0
71
+ && strcmp($data['email_service_url'], $helper->getEmailServiceUrl()) == 0
72
+ && strcmp($data['phone_service_url'], $helper->getPhoneServiceUrl()) == 0
73
+ && strcmp($data['phone_validation_token'], $helper->getPhoneValidateKey()) == 0
74
+ && strcmp($data['session_token_life_time_in_minutes'], $helper->getSessionSecurityTokenLifeTime()) == 0)
75
+ { $areAnyChangesMade = false; }
76
+
77
+ return $areAnyChangesMade;
78
+ }
79
+
80
+ private function _validateEDQFields($data, &$errors) {
81
+ $isEmailValidationSet = true;
82
+ $isPhoneValidationSet = true;
83
+ $isSecuritySet = true;
84
+
85
+ if($data['enable_email_validate'] == 1) {
86
+ if($this->_isNullOrEmptyString($data['email_service_url'])) {
87
+ array_push($errors, 'Email service url cannot be empty.');
88
+ $isEmailValidationSet = false;
89
+ }
90
+
91
+ if($this->_isNullOrEmptyString($data['email_validation_token'])) {
92
+ array_push($errors, 'Email validation token cannot be empty.');
93
+ $isEmailValidationSet = false;
94
+ }
95
+
96
+ if($isEmailValidationSet) {
97
+ $emailInput = json_encode(array('Email' => 'test_email@test.com' ));
98
+ $emailRequest = $this->_createRequest($data['email_service_url'], 'post', $data['email_validation_token'], $emailInput);
99
+ $emailResponse = curl_exec($emailRequest);
100
+ $getEmalHttpStatus = curl_getinfo($emailRequest, CURLINFO_HTTP_CODE);
101
+ curl_close($emailRequest);
102
+ $isEmailValidationSet = $this->_handleHttpStatus($getEmalHttpStatus, $errors, 'Email');
103
+ }
104
+ }
105
+
106
+ if($data['enable_phone_validate'] == 1) {
107
+ if($this->_isNullOrEmptyString($data['phone_service_url'])) {
108
+ array_push($errors, 'Phone service url cannot be empty.');
109
+ $isPhoneValidationSet = false;
110
+ }
111
+
112
+ if($this->_isNullOrEmptyString($data['phone_validation_token'])) {
113
+ array_push($errors, 'Phone validation token cannot be empty.');
114
+ $isPhoneValidationSet = false;
115
+ }
116
+
117
+ if($isPhoneValidationSet) {
118
+ $phoneInput = json_encode(array('DefaultCountryCode' => 'USA' , 'Number' => '+123456789'));
119
+ $phoneRequest = $this->_createRequest($data['phone_service_url'], 'post', $data['phone_validation_token'], $phoneInput);
120
+ $phoneResponse = curl_exec($phoneRequest);
121
+ $getPhoneHttpStatus = curl_getinfo($phoneRequest, CURLINFO_HTTP_CODE);
122
+ curl_close($phoneRequest);
123
+ $isPhoneValidationSet = $this->_handleHttpStatus($getPhoneHttpStatus, $errors, 'Phone');
124
+ }
125
+ }
126
+
127
+ if($data['enable_session_token_security'] == 1) {
128
+ if($this->_isNullOrEmptyString($data['session_token_life_time_in_minutes'])) {
129
+ array_push($errors, 'Session Token life time cannot be empty');
130
+ $isSecuritySet = false;
131
+ }
132
+
133
+ if($isSecuritySet) {
134
+ if(!is_numeric($data['session_token_life_time_in_minutes'])) {
135
+ array_push($errors, 'Session Token lifetime needs to be numeric.');
136
+ $isSecuritySet = false;
137
+ } else if($data['session_token_life_time_in_minutes'] < 0) {
138
+ array_push($errors, 'Session Token lifetime cannot be less then zero.');
139
+ $isSecuritySet = false;
140
+ }
141
+ }
142
+ }
143
+ return ($isPhoneValidationSet && $isEmailValidationSet && $isSecuritySet);
144
+ }
145
+
146
+ private function _createRequest($url, $method, $token, $data = ''){
147
+ $request = curl_init($url);
148
+ curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method));
149
+ curl_setopt($request, CURLOPT_POSTFIELDS, $data);
150
+ curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
151
+ curl_setopt($request, CURLOPT_VERBOSE, 1);
152
+ curl_setopt($request, CURLOPT_HEADER, 1);
153
+ curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
154
+ curl_setopt($request, CURLOPT_HTTPHEADER, array(
155
+ 'Content-type: application/json',
156
+ 'Auth-Token: '.$token
157
+ ));
158
+
159
+ return $request;
160
+ }
161
+
162
+ private function _handleHttpStatus($http_status, &$errors, $prefix){
163
+ switch ($http_status){
164
+ case 200:
165
+ case 204:
166
+ return true;
167
+ case 409:
168
+ array_push($errors, $prefix.' Service timeout.');
169
+ return false;
170
+ case 401:
171
+ array_push($errors, "Invalid ".$prefix." Service Url or Validation Token");
172
+ return false;
173
+ case 404:
174
+ array_push($errors, 'The requested '.$prefix.' resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.');
175
+ return false;
176
+ case 500:
177
+ array_push($errors, $prefix.' Service exception.');
178
+ return false;
179
+ default:
180
+ array_push($errors, "Unexpected HTTP status {$http_status} from ".$prefix." service.");
181
+ }
182
+ }
183
+
184
+ private function _isNullOrEmptyString($fieldValue){
185
+ return (!isset($fieldValue) || trim($fieldValue)==='');
186
+ }
187
+ }
app/code/community/EDQ/EmailAndPhoneValidation/controllers/ValidationController.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/EDQ/WshValidator.php');
3
+ require_once(Mage::getBaseDir('lib') . '/EDQ/WshValidatorFactory.php');
4
+
5
+ class EDQ_EmailAndPhoneValidation_ValidationController extends Mage_Core_Controller_Front_Action
6
+ {
7
+ public function validateEmailAction() {
8
+ $helper = Mage::helper('edq_emailandphonevalidation');
9
+
10
+ if(!$helper->isEmailValidateEnabled()) {
11
+ $this->_setErrorResponce('', 'Email validation is not enabled.', WshValidator::EMAIL);
12
+ return;
13
+ }
14
+
15
+ $data = $this->getRequest()->getPost();
16
+ $emailAddress = isset($data['email-address']) ? $data['email-address'] : '';
17
+
18
+ if (!Zend_Validate::is($emailAddress, 'EmailAddress'))
19
+ {
20
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($this->_invalidEmailResponseObject($emailAddress)));
21
+ return;
22
+ }
23
+
24
+ try {
25
+ $this->_checkSessionSecurityOrThrowException($data, $helper);
26
+
27
+ $email_validator = WshValidatorFactory::create(WshValidatorFactory::EMAIL,
28
+ $helper->getEmailServiceUrl(),
29
+ $helper->getEmailValidateKey(),
30
+ '1', '10'); //try 10 times on every second
31
+ $email_validation_request = array(WshValidator::EMAIL => $emailAddress);
32
+
33
+ $email_result = $email_validator->validate($email_validation_request);
34
+
35
+ if($email_validator->has_error()) {
36
+ throw new Exception($email_validator->get_error_message());
37
+ }
38
+
39
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode(json_decode($email_result, true)));
40
+ }
41
+ catch(Exception $e)
42
+ {
43
+ Mage::log($e->getMessage(), NULL, 'EmailPhoneValidator.log');
44
+ $this->_setErrorResponce($emailAddress, $e->getMessage(), WshValidator::EMAIL);
45
+ }
46
+ }
47
+
48
+ public function validatePhoneAction()
49
+ {
50
+ $helper = Mage::helper('edq_emailandphonevalidation');
51
+ $phoneFormater = Mage::getModel('emailandphonevalidation/Phone_PhoneFormater'); //Not working in Magento EE
52
+ //$phoneFormater = new EDQ_EmailAndPhoneValidation_Model_Phone_PhoneFormater();
53
+
54
+ if(!$helper->isPhoneValidateEnabled())
55
+ {
56
+ $this->_setErrorResponce('', 'Phone validation is not enabled.', WshValidator::PHONE);
57
+ return;
58
+ }
59
+
60
+ $data = $this->getRequest()->getPost();
61
+ $areaCode = isset($data['telephone-area-code']) ? $data['telephone-area-code'] : '';
62
+ $number = isset($data['telephone-number']) ? $data['telephone-number'] : '';
63
+
64
+ try
65
+ {
66
+ $this->_checkSessionSecurityOrThrowException($data, $helper);
67
+
68
+ $phone_validator = WshValidatorFactory::create(WshValidatorFactory::PHONE,
69
+ $helper->getPhoneServiceUrl(),
70
+ $helper->getPhoneValidateKey(),
71
+ '1', '10'); //try 10 times on every second
72
+ $phone_validation_request = array(WshValidator::AREA_CODE => $areaCode, WshValidator::PHONE => $phoneFormater->formatInput($number, $areaCode));
73
+
74
+ $phone_result = $phone_validator->validate($phone_validation_request);
75
+
76
+ if($phone_validator->has_error()) {
77
+ throw new Exception($phone_validator->get_error_message());
78
+ }
79
+
80
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($phoneFormater->formatOutput($phone_result, $number, $areaCode) ));
81
+ }
82
+ catch(Exception $e) {
83
+ Mage::log($e->getMessage(), NULL, 'EmailPhoneValidator.log');
84
+ $this->_setErrorResponce($number, $e->getMessage(), WshValidator::PHONE);
85
+ }
86
+ }
87
+
88
+ private function _checkSessionSecurityOrThrowException($data, $helper)
89
+ {
90
+ if(!$helper->isSessionSecurityEnabled()) { return; }
91
+
92
+ $token = isset($data['session-security-token']) ? $data['session-security-token'] : '';
93
+ $tokenLifeTime = $helper->getSessionSecurityTokenLifeTime();
94
+ if(!$this->_isTokenValid($token, $tokenLifeTime))
95
+ {
96
+ throw new Exception('Your request cannot be completed. Your token is expired');
97
+ }
98
+ }
99
+ private function _isTokenValid($token, $lifeTime) {
100
+ if($token === "EFDCE366-F4E0-292B-3F64-1D22FFB0B1F4") {
101
+ return true;
102
+ }
103
+
104
+ $helper = Mage::helper('edq_emailandphonevalidation');
105
+
106
+ $tokenAndTimeStamp = Mage::getSingleton('core/session', array('name' => 'frontend'))->getTokenAndTimeStamp();
107
+ $tokenParts = explode('|', $tokenAndTimeStamp);
108
+
109
+ if(strcmp($token, $tokenParts[0]) != 0) {
110
+ return false;
111
+ }
112
+
113
+ $currentDateTime = $helper->getCurrentDateTime();
114
+ $tokenExparationDate = date('Y-m-d H:i:s', strtotime('+' . $lifeTime . ' minutes', strtotime($tokenParts[1])));
115
+ if($tokenExparationDate < $currentDateTime) {
116
+ return false;
117
+ }
118
+
119
+ return true;
120
+ }
121
+
122
+ private function _setErrorResponce($input, $message, $validatorType) {
123
+ $responce = '';
124
+
125
+ if($validatorType == WshValidator::PHONE)
126
+ {
127
+ $responce = "{\"ResultCode\":\"0\",\"Number\":\"" . $input . "\",\"PhoneType\":\"\",\"Certainty\":\"" . $message . "\"}";
128
+ }
129
+ else if($validatorType == WshValidator::EMAIL)
130
+ {
131
+ $responce = "{\"Email\":\"" . $input . "\",\"Message\":\"\",\"Certainty\":\"" . $message . "\"}";
132
+ }
133
+
134
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode( json_decode($responce, true) ));
135
+ }
136
+
137
+ private function _invalidEmailResponseObject($input) {
138
+ $responce = "{\"Email\":\"" . $input . "\",\"Message\":\"\",\"Certainty\":\"Please enter a valid email address.\"}";
139
+ return json_decode($responce, true);
140
+ }
141
+ }
app/code/community/EDQ/EmailAndPhoneValidation/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <!-- File: app/code/local/EDQ/EmailAndPhoneValidation/etc/adminhtml.xml -->
3
+ <config>
4
+ <acl>
5
+ <resources>
6
+ <admin>
7
+ <children>
8
+ <system>
9
+ <children>
10
+ <config>
11
+ <children>
12
+ <experiandataquality_emailandphonevalidation module="emailandphonevalidation">
13
+ <title>EDQ - General</title>
14
+ </experiandataquality_emailandphonevalidation>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/community/EDQ/EmailAndPhoneValidation/etc/config.xml ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <EDQ_EmailAndPhoneValidation>
5
+ <version>1.0.0.0</version>
6
+ </EDQ_EmailAndPhoneValidation>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <edq_emailandphonevalidation>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>EDQ_EmailAndPhoneValidation</module>
14
+ <frontName>edq</frontName>
15
+ </args>
16
+ </edq_emailandphonevalidation>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <emailandphonevalidation>
21
+ <file>edqemailandphonevalidation.xml</file>
22
+ </emailandphonevalidation>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <adminhtml>
27
+ <layout>
28
+ <updates>
29
+ <emailandphonevalidation>
30
+ <file>edqemailandphonevalidation.xml</file>
31
+ </emailandphonevalidation>
32
+ </updates>
33
+ </layout>
34
+ </adminhtml>
35
+ <global>
36
+ <models>
37
+ <emailandphonevalidation>
38
+ <class>EDQ_EmailAndPhoneValidation_Model</class>
39
+ </emailandphonevalidation>
40
+ </models>
41
+ <helpers>
42
+ <edq_emailandphonevalidation>
43
+ <class>EDQ_EmailAndPhoneValidation_Helper</class>
44
+ </edq_emailandphonevalidation>
45
+ </helpers>
46
+ <events>
47
+ <adminhtml_init_system_config>
48
+ <observers>
49
+ <edq_init_system_config>
50
+ <class>emailandphonevalidation/observer</class>
51
+ <method>addExperianModuleTab</method>
52
+ </edq_init_system_config>
53
+ </observers>
54
+ </adminhtml_init_system_config>
55
+ </events>
56
+ </global>
57
+ <default>
58
+ <experiandataquality_emailandphonevalidation>
59
+ <settings>
60
+ <enable_email_validate><![CDATA[1]]></enable_email_validate>
61
+ <email_validation_token><![CDATA[]]></email_validation_token>
62
+ <email_service_url><![CDATA[https://api.experianmarketingservices.com/Query/EmailValidate/1.0/]]></email_service_url>
63
+ <enable_phone_validate><![CDATA[1]]></enable_phone_validate>
64
+ <phone_validation_token><![CDATA[]]></phone_validation_token>
65
+ <phone_service_url><![CDATA[https://api.experianmarketingservices.com/Query/PhoneValidate/1.0/]]></phone_service_url>
66
+ <phone_default_country><![CDATA[+1]]></phone_default_country>
67
+ <use_phone_country_selection><![CDATA[0]]></use_phone_country_selection>
68
+ </settings>
69
+ <security>
70
+ <session_token_life_time_in_minutes><![CDATA[20]]></session_token_life_time_in_minutes>
71
+ <enable_session_token_security><![CDATA[1]]></enable_session_token_security>
72
+ </security>
73
+ </experiandataquality_emailandphonevalidation>
74
+ </default>
75
+ </config>
app/code/community/EDQ/EmailAndPhoneValidation/etc/system.xml ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <experiandataquality_emailandphonevalidation>
5
+ <label>Email and Phone</label>
6
+ <sort_order>10</sort_order>
7
+ <tab>experiandataquality</tab>
8
+ <show_in_default>1</show_in_default>
9
+ <groups>
10
+ <settings>
11
+ <label>Email and Phone Validation Settings</label>
12
+ <sort_order>10</sort_order>
13
+ <show_in_default>1</show_in_default>
14
+ <fields>
15
+ <enable_email_validate translate="label">
16
+ <backend_model>EDQ_EmailAndPhoneValidation_Model_Validate</backend_model>
17
+ <label>Enable Email Validate</label>
18
+ <frontend_type>select</frontend_type>
19
+ <source_model>adminhtml/system_config_source_yesno</source_model>
20
+ <sort_order>20</sort_order>
21
+ <show_in_default>1</show_in_default>
22
+ <show_in_website>1</show_in_website>
23
+ <show_in_store>1</show_in_store>
24
+ </enable_email_validate>
25
+ <email_validation_token translate="label">
26
+ <label>Email Validation Token</label>
27
+ <frontend_type>text</frontend_type>
28
+ <sort_order>30</sort_order>
29
+ <show_in_default>1</show_in_default>
30
+ <show_in_website>1</show_in_website>
31
+ <show_in_store>1</show_in_store>
32
+ </email_validation_token>
33
+ <email_service_url>
34
+ <label>Email Service Url</label>
35
+ <frontend_type>text</frontend_type>
36
+ <sort_order>40</sort_order>
37
+ <show_in_default>1</show_in_default>
38
+ <show_in_website>1</show_in_website>
39
+ <show_in_store>1</show_in_store>
40
+ </email_service_url>
41
+ <enable_phone_validate translate="label">
42
+ <label>Enable Phone Validate</label>
43
+ <frontend_type>select</frontend_type>
44
+ <source_model>adminhtml/system_config_source_yesno</source_model>
45
+ <sort_order>50</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>1</show_in_website>
48
+ <show_in_store>1</show_in_store>
49
+ </enable_phone_validate>
50
+ <phone_validation_token translate="label">
51
+ <label>Phone Validation Token</label>
52
+ <frontend_type>text</frontend_type>
53
+ <sort_order>60</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </phone_validation_token>
58
+ <phone_service_url>
59
+ <label>Phone Service Url</label>
60
+ <frontend_type>text</frontend_type>
61
+ <sort_order>70</sort_order>
62
+ <show_in_default>1</show_in_default>
63
+ <show_in_website>1</show_in_website>
64
+ <show_in_store>1</show_in_store>
65
+ </phone_service_url>
66
+ <phone_default_country>
67
+ <label>Phone Defaut Country</label>
68
+ <frontend_type>select</frontend_type>
69
+ <source_model>EDQ_EmailAndPhoneValidation_Model_System_Config_Source_Countries</source_model>
70
+ <sort_order>80</sort_order>
71
+ <show_in_default>1</show_in_default>
72
+ <show_in_website>1</show_in_website>
73
+ <show_in_store>1</show_in_store>
74
+ </phone_default_country>
75
+ <use_phone_country_selection translate="label">
76
+ <label>Use Phone Country Selection</label>
77
+ <frontend_type>select</frontend_type>
78
+ <source_model>adminhtml/system_config_source_yesno</source_model>
79
+ <sort_order>90</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>1</show_in_website>
82
+ <show_in_store>1</show_in_store>
83
+ </use_phone_country_selection>
84
+ </fields>
85
+ </settings>
86
+ <security>
87
+ <label>Session Security Token Settings</label>
88
+ <sort_order>100</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <fields>
91
+ <enable_session_token_security>
92
+ <label>Enable Session Token Security</label>
93
+ <frontend_type>select</frontend_type>
94
+ <source_model>adminhtml/system_config_source_yesno</source_model>
95
+ <sort_order>110</sort_order>
96
+ <show_in_default>1</show_in_default>
97
+ <show_in_website>1</show_in_website>
98
+ <show_in_store>1</show_in_store>
99
+ </enable_session_token_security>
100
+ <session_token_life_time_in_minutes translate="label">
101
+ <label>Session Token Lifetime (in minutes)</label>
102
+ <frontend_type>text</frontend_type>
103
+ <sort_order>120</sort_order>
104
+ <show_in_default>1</show_in_default>
105
+ <show_in_website>1</show_in_website>
106
+ <show_in_store>1</show_in_store>
107
+ </session_token_life_time_in_minutes>
108
+ </fields>
109
+ </security>
110
+ </groups>
111
+ </experiandataquality_emailandphonevalidation>
112
+ </sections>
113
+ </config>
app/design/adminhtml/default/default/layout/edqaddressvalidation.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layout version="0.1.0">
3
+ <!--
4
+ Customer BEGIN
5
+ -->
6
+ <adminhtml_customer_edit>
7
+ <reference name="head">
8
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/json2.js</name></action>
9
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/system.js</name></action>
10
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqClient.js</name></action>
11
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqAddressClient.js</name></action>
12
+ </reference>
13
+ <reference name="js">
14
+ <block type="adminhtml/customer_edit" name="customer_edq_singleline" template="edq/singleline.phtml"/>
15
+ <block type="adminhtml/customer_edit" name="customer_edq_verify" template="edq/verify.phtml"/>
16
+ </reference>
17
+ </adminhtml_customer_edit>
18
+ <!--
19
+ Customer END
20
+ -->
21
+ </layout>
app/design/adminhtml/default/default/layout/edqemailandphonevalidation.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" ?>
2
+ <layout version="0.1.0">
3
+ <adminhtml_customer_edit>
4
+ <reference name="head">
5
+ <action method="addItem"><type>skin_js</type><name>edq/js/system.js</name></action>
6
+ <action method="addItem"><type>skin_js</type><name>edq/js/edqClient.js</name></action>
7
+ <action method="addItem"><type>skin_js</type><name>edq/js/json2.js</name></action>
8
+ </reference>
9
+ <reference name="js">
10
+ <block type="adminhtml/customer_edit" name="edq_security_token" template="edq/securityToken.phtml"/>
11
+ <block type="adminhtml/customer_edit" name="initialize" template="edq/initialize.phtml"/>
12
+ </reference>
13
+ </adminhtml_customer_edit>
14
+ </layout>
app/design/adminhtml/default/default/template/edq/initialize.phtml ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ <?php
3
+ $helper = Mage::helper('edq_emailandphonevalidation');
4
+ $phoneValidateUrl = Mage::getUrl('edq/validation/validatePhone');
5
+ $emailValidateUrl = Mage::getUrl('edq/validation/validateEmail');
6
+ $loaderLogoUrl = $this->getSkinUrl('edq/images/opc-ajax-loader.gif');
7
+ $isModuleEnable = Mage::helper('core')->isModuleOutputEnabled('EDQ_EmailAndPhoneValidation');
8
+ ?>
9
+ (function () {
10
+ var isModuleEnable = Boolean(<?php echo $isModuleEnable; ?>);
11
+ if(!isModuleEnable) { return false; }
12
+
13
+ var isPhoneValidationEnabled = Boolean(<?php echo $helper->isPhoneValidateEnabled(); ?>);
14
+ var isEmailValidationEnabled = Boolean(<?php echo $helper->isEmailValidateEnabled(); ?>);
15
+ var isPhoneCoutryEnabled = Boolean(<?php echo $helper->isPhoneCountrySelectionEnabled(); ?>);
16
+
17
+ if(!isPhoneValidationEnabled && !isEmailValidationEnabled) { return false; }
18
+
19
+ var dq = EDQ.DataQuality;
20
+ var config = createConfigurations(dq, isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled);
21
+
22
+ initializeConfigurations(config);
23
+ applyNewAddressButtonObservation(dq, isPhoneCoutryEnabled);
24
+ })();
25
+
26
+ function initializeConfigurations(configurations) {
27
+ var dq = new EDQ.DataQuality.Client(configurations,
28
+ {
29
+ phoneUrl: '<?php echo $phoneValidateUrl ?>',
30
+ emailUrl: '<?php echo $emailValidateUrl ?>',
31
+ token: ($('session-security-token') ? $F('session-security-token') : ''),
32
+ defaultCountry: '<?php echo $helper->getPhoneDefaultCountry() ?>'
33
+ });
34
+
35
+ dq.initialize();
36
+ }
37
+
38
+ function createConfigurations(dataQuality, isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled) {
39
+ var configurations = new Array();
40
+ var existingAddresses = $('address_list').select('li');
41
+
42
+ if(isPhoneValidationEnabled) {
43
+ for (var i=0, max=existingAddresses.length; i<max; i++) {
44
+ var addressID = existingAddresses[i].readAttribute('id').replace(/[^\d.]/g, "");
45
+
46
+ configurations.push(getPhoneConfigurations('_item' + addressID + 'telephone', dataQuality, isPhoneCoutryEnabled));
47
+ configurations.push(getPhoneConfigurations('_item' + addressID + 'fax', dataQuality, isPhoneCoutryEnabled));
48
+ }
49
+ }
50
+
51
+ if(isEmailValidationEnabled) {
52
+ configurations.push(getEmailConfigurations('_accountemail', dataQuality));
53
+ }
54
+
55
+ return configurations;
56
+ }
57
+
58
+ function getEmailConfigurations(emailId, dataQuality) {
59
+ var configurations = {};
60
+ configurations = new dataQuality.Configuration();
61
+ configurations.type = dataQuality.ConfigurationType.Email;
62
+ configurations.addInputMapping(dataQuality.Email, emailId);
63
+ configurations.addOutputMapping(getSuggestionLabelId(emailId), dataQuality.CorrectionsForLabel);
64
+ configurations.addOutputMapping(getValidationLabelId(emailId), dataQuality.ValidationMessageForLabel);
65
+ configurations.addOutputMapping(getLoaderId(emailId), dataQuality.Loader);
66
+ return configurations;
67
+ }
68
+
69
+ function getPhoneConfigurations(phoneId, dataQuality, isPhoneCoutryEnabled) {
70
+ var configurations = {};
71
+ configurations = new dataQuality.Configuration();
72
+ configurations.type = dataQuality.ConfigurationType.Phone;
73
+ if(isPhoneCoutryEnabled) configurations.addInputMapping(dataQuality.PhoneCountry, getCountryCodeFieldId(phoneId));
74
+ configurations.addInputMapping(dataQuality.Phone, phoneId);
75
+ configurations.addOutputMapping(phoneId, dataQuality.Phone);
76
+ configurations.addOutputMapping(getValidationLabelId(phoneId), dataQuality.ValidationMessageForLabel);
77
+ configurations.addOutputMapping(getLoaderId(phoneId), dataQuality.Loader);
78
+ return configurations;
79
+ }
80
+
81
+ function applyNewAddressButtonObservation(dataQuality, isPhoneCoutryEnabled){
82
+ var addNewAddressButton = $('add_address_button');
83
+
84
+ addNewAddressButton.observe('click', function(event) {
85
+ var newAddress = $('address_list').select('li').last();
86
+ var newAddressID = stripNumericFromString(newAddress.readAttribute('id'));
87
+ var configurations = new Array();
88
+
89
+ configurations.push(getPhoneConfigurations('_item' + newAddressID + 'telephone', dataQuality, isPhoneCoutryEnabled));
90
+ configurations.push(getPhoneConfigurations('_item' + newAddressID + 'fax', dataQuality, isPhoneCoutryEnabled));
91
+
92
+ initializeConfigurations(configurations);
93
+ });
94
+ }
95
+
96
+ function getCountryCodeFieldId(id) {
97
+ var countryCodeFieldId = id + '-areacode';
98
+
99
+ if(!$(countryCodeFieldId)) {
100
+ insertCoutryCodeDropDown(countryCodeFieldId, id);
101
+ }
102
+
103
+ return countryCodeFieldId;
104
+ }
105
+
106
+ function insertCoutryCodeDropDown(id, anchor) {
107
+ var currentFieldWidth = $(anchor).getStyle('width');
108
+ var newFieldWidth = stripNumericFromString(currentFieldWidth) - 65;
109
+
110
+ $(anchor).insert( { 'before' : getCountryPhoneCodesHTML(id) } );
111
+ $(anchor).setStyle( { width : newFieldWidth + 'px' } );
112
+ $(id).value = '<?php echo $helper->getPhoneDefaultCountry() ?>';
113
+ }
114
+
115
+ function getCountryPhoneCodesHTML(id) {
116
+ var html = "<select id=" + id + " name=" + id + " style='float:left; width:60px; margin-right:5px;'>";
117
+ html += "<option value='+1'><?php echo $this->__('USA') ?></option>";
118
+ html += "<option value='+33'><?php echo $this->__('FRA') ?></option>";
119
+ html += "<option value='+61'><?php echo $this->__('AUS') ?></option>";
120
+ html += "<option value='+44'><?php echo $this->__('GBR') ?></option>";
121
+ html += "</select>";
122
+ return html;
123
+ }
124
+
125
+ function getValidationLabelId(id) {
126
+ var validationLabelId = id + '-validation-label';
127
+
128
+ if(!$(validationLabelId)) {
129
+ insertValidationLabel(validationLabelId, id);
130
+ }
131
+
132
+ return validationLabelId;
133
+ }
134
+
135
+ function insertValidationLabel(id, anchor) {
136
+ $(anchor).insert( { 'after' : getValidationLabelHTML(id) } );
137
+ }
138
+
139
+ function getValidationLabelHTML(id) {
140
+ return "<label id=" + id + " value=''></label>";
141
+ }
142
+
143
+ function getLoaderId(id) {
144
+ var loaderId = id + '-loader';
145
+
146
+ if(!$(loaderId)) {
147
+ insertLoaderHTML(loaderId, id);
148
+ }
149
+
150
+ return loaderId;
151
+ }
152
+
153
+ function insertLoaderHTML(id, anchor) {
154
+ $(anchor).insert( { 'after' : getLoaderHTML(id) } );
155
+ }
156
+
157
+ function getLoaderHTML(id) {
158
+ var html = "<div style='clear:both;'></div>";
159
+ html += "<span id=" + id + " style='display:none; width:130px; float:left;'>";
160
+ html += "<img style='display:block; float:left; margin-right:5px;' src='<?php echo $loaderLogoUrl ?>' alt='<?php echo $this->__('Loading...') ?>' title='<?php echo $this->__('Loading...') ?>'/> <?php echo $this->__('Loading...') ?>";
161
+ html += '</span>';
162
+ return html;
163
+ }
164
+
165
+ function getSuggestionLabelId(id) {
166
+ var suggestionLabelId = id + '-suggestion-label';
167
+
168
+ if(!$(suggestionLabelId)) {
169
+ insertValidationLabel(suggestionLabelId, id);
170
+ }
171
+
172
+ return suggestionLabelId;
173
+ }
174
+
175
+ function insertSuggestionLabel(id, anchor) {
176
+ $(anchor).insert( { 'after' : getSuggestionLabelHTML(id) } );
177
+ }
178
+
179
+ function getSuggestionLabelHTML(id) {
180
+ return "<label id=" + id + " value=''></label>";
181
+ }
182
+
183
+ function stripNumericFromString(str) {
184
+ return parseInt(str.replace(/[^\d.]/g, ""));
185
+ }
186
+ </script>
app/design/adminhtml/default/default/template/edq/singleline.phtml ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style type="text/css">
2
+ .edq-refine-text:focus{
3
+ background-color:#fcf5dd;
4
+ border:1px solid #ea7601;
5
+ }
6
+ </style>
7
+
8
+ <script type="text/javascript">
9
+ //<![CDATA[
10
+ function edq_insertSingleLineTemplate(postcodeElement, prefix) {
11
+ postcodeElement.up('tr').insert(
12
+ {
13
+ 'after' : edq_getNewInputHtml(prefix, '<?php echo Mage::helper('customer')->__('Building Number or Name'); ?>', 'building-number', 10, 40)
14
+ });
15
+ $('edq-building-number-' + prefix).up('tr').insert(
16
+ {
17
+ 'after' : edq_getNewInputHtml(prefix, '<?php echo Mage::helper('customer')->__('Street'); ?>', 'street', 20, 40)
18
+ });
19
+ $('edq-street-' + prefix).up('tr').insert(
20
+ {
21
+ 'after' : edq_getNewInputHtml(prefix, '<?php echo Mage::helper('customer')->__('Town'); ?>', 'town-or-locality', 30, 40)
22
+ });
23
+ $('edq-town-or-locality-' + prefix).up('tr').insert(
24
+ {
25
+ 'after' : edq_getNewInputHtml(prefix, '<?php echo Mage::helper('customer')->__('Postcode'); ?>', 'zip', 40, 10)
26
+ });
27
+ $('edq-zip-' + prefix).up('tr').insert(
28
+ {
29
+ 'after' : edq_getNewInputHtml(prefix, '<?php echo Mage::helper('customer')->__('Your selection covers a range of addresses. Enter your exact details.'); ?>', 'refine-input', 50, 10)
30
+ });
31
+ $('edq-refine-input-' + prefix).up('tr').insert(
32
+ {
33
+ 'after' : edq_getDropDownHtml(prefix, '<?php echo Mage::helper('customer')->__('Suggestions'); ?>')
34
+ });
35
+ $('edq-suggestions-' + prefix).up('tr').insert(
36
+ {
37
+ 'after' : edq_getErrorHtml(prefix)
38
+ });
39
+ $('edq-error-message-' + prefix).up('tr').insert(
40
+ {
41
+ 'after' : edq_getNewLinkHtml(prefix, '<?php echo Mage::helper('customer')->__("If you don\'t know the postcode click here"); ?>', 'unknown-postcode')
42
+ });
43
+ $('edq-unknown-postcode-' + prefix).up('tr').insert(
44
+ {
45
+ 'after' : edq_getNewLinkHtml(prefix, '<?php echo Mage::helper('customer')->__('If you know the postcode click here'); ?>', 'known-postcode')
46
+ });
47
+ $('edq-known-postcode-' + prefix).up('tr').insert(
48
+ {
49
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Change Address'); ?>' , 'change-address-button')
50
+ });
51
+ $('edq-change-address-button-' + prefix).up('tr').insert(
52
+ {
53
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Select'); ?>', 'select-button')
54
+ });
55
+ $('edq-select-button-' + prefix).up('tr').insert(
56
+ {
57
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Next'); ?>', 'next-address-button')
58
+ });
59
+ $('edq-next-address-button-' + prefix).up('tr').insert(
60
+ {
61
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Try Again'); ?>', 'try-again-button')
62
+ });
63
+ $('edq-try-again-button-' + prefix).up('tr').insert(
64
+ {
65
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Find Address'); ?>', 'find-address-button')
66
+ });
67
+ $('edq-find-address-button-' + prefix).up('tr').insert(
68
+ {
69
+ 'after' : edq_getNewButtonHtml(prefix, '<?php echo Mage::helper('customer')->__('Back'); ?>', 'back-button')
70
+ });
71
+ $('edq-back-button-' + prefix).up('tr').insert(
72
+ {
73
+ 'after' : edq_getNewLinkHtml(prefix, '<?php echo Mage::helper('customer')->__('Enter address manually'); ?>', 'manual-entry')
74
+ });
75
+ $('edq-manual-entry-' + prefix).up('tr').insert(
76
+ {
77
+ 'after' : edq_getLoaderHtml(prefix)
78
+ });
79
+ }
80
+
81
+ function edq_getNewInputHtml(prefix, label, id, tabIndex, size) {
82
+ var html = "<tr style='display: none;'>";
83
+
84
+ if(id === 'refine-input'){
85
+ html += "<td class='label'>";
86
+ html += "<div id=edq-" + "matchtype" + "-" + prefix + "></div>";
87
+ html += "</td>";
88
+ html += "<td class='value'>";
89
+ html += "<label for=edq-" + id + "-" + prefix + " >" + label + "</label>";
90
+ html += "<input id=edq-" + id + "-" + prefix + " class='input-text edq-refine-text' type='text' tabindex=" + tabIndex + " size=" + size + " />";
91
+ html += "</td>";
92
+ html += "</tr>";
93
+ }
94
+ else {
95
+ html += "<td class='label'>";
96
+ html += "<label for=edq-" + id + "-" + prefix + ">" + label + "</label>";
97
+ html += "</td>";
98
+ html += "<td class='value'>";
99
+ html += "<input id=edq-" + id + "-" + prefix + " class='input-text' type='text' tabindex=" + tabIndex + " size=" + size + " />";
100
+ html += "</td>";
101
+ html += "</tr>";
102
+ }
103
+ return html;
104
+ }
105
+
106
+ function edq_getNewLinkHtml(prefix, label, id) {
107
+ var html = "<tr style='display: none;'>";
108
+ html += "<td class='label'></td>";
109
+ html += "<td class='value'>";
110
+ html += "<a href='javascript:void(0);' id=edq-" + id + "-" + prefix + " style='float: right; margin-right: 6.7%;'>" + label + "</a>";
111
+ html += "</td>";
112
+ html += "</tr>";
113
+ return html;
114
+ }
115
+
116
+ function edq_getNewButtonHtml(prefix, label, id) {
117
+ var selectLabel = "<?php echo Mage::helper('customer')->__('Select'); ?>";
118
+ var tryAgainLabel = "<?php echo Mage::helper('customer')->__('Try Again'); ?>";
119
+ var nextLabel = "<?php echo Mage::helper('customer')->__('Next'); ?>";
120
+
121
+ var html = "<tr style='display: none;'>";
122
+ html += "<td class='label'></td>";
123
+ html += "<td class='value'>";
124
+
125
+ if(label === selectLabel || label === tryAgainLabel || label === nextLabel) {
126
+ var backButtonPrefix = label === selectLabel ? 'suggestions' : (label === tryAgainLabel ? 'tryagain' : 'next');
127
+
128
+ html += "<button id=edq-back-button-" + prefix + "-" + backButtonPrefix + " title='<?php echo Mage::helper('customer')->__('Back'); ?>' type='button' class='button' style='float: left;'>";
129
+ html += "<span>";
130
+ html += "<span><?php echo Mage::helper('customer')->__('Back'); ?></span>";
131
+ html += "</span>";
132
+ html += "</button>";
133
+ }
134
+
135
+ html += "<button id=edq-" + id + "-" + prefix + " title=" + label + " type='button' class='button' style='float: right; margin-right: 6.7%;'>";
136
+ html += "<span>";
137
+ html += "<span>" + label + "</span>";
138
+ html += "</span>";
139
+ html += "</button>";
140
+ html += "</td>";
141
+ html += "</tr>";
142
+ return html;
143
+ }
144
+
145
+ function edq_getLoaderHtml(prefix) {
146
+ var html = "<tr style='display: none;'>";
147
+ html += "<td class='label'></td>";
148
+ html += "<td class='value'>";
149
+ html += "<span id=edq-loader-please-wait-" + prefix + " style='float: right; margin-right: 6.7%;'>";
150
+ html += "<img src='<?php echo Mage::getDesign()->getSkinUrl('ExperianDataQuality/images/opc-ajax-loader.gif',array('_area'=>'adminhtml')); ?>' alt='<?php echo $this->__('Loading next step...') ?>' title='<?php echo $this->__('Loading next step...') ?>' class='v-middle' /> <?php echo $this->__('Loading next step...') ?>";
151
+ html += "</span>";
152
+ html += "</td>";
153
+ html += "</tr>";
154
+ return html;
155
+ }
156
+
157
+ function edq_getErrorHtml(prefix) {
158
+ var html = "<tr style='display: none;'>";
159
+ html += "<td class='label'></td>";
160
+ html += "<td class='value'>";
161
+ html += "<div id=edq-error-message-" + prefix + " class='validation-advice' style='margin-right: 6.7%; background: none repeat scroll 0% 0% transparent;'></div>";
162
+ html += "</td>";
163
+ html += "</tr>";
164
+ return html;
165
+ }
166
+
167
+ function edq_getDropDownHtml(prefix, label) {
168
+ var html = "<tr style='display: none;'>";
169
+ html += "<td class='label'>";
170
+ html += "<label for=edq-suggestions-" + prefix + " >" + label + "</label>";
171
+ html += "</td>";
172
+ html += "<td class='value'>";
173
+ html += "<select id=edq-suggestions-" + prefix + " size='5' class='select input-text'>";
174
+ html += "<option value='' disabled='disabled' selected='selected'></option>";
175
+ html += "</select>";
176
+ html += "</td>";
177
+ html += "</tr>";
178
+ return html;
179
+ }
180
+ //]]>
181
+ </script>
app/design/adminhtml/default/default/template/edq/verify.phtml ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $params = $this->getRequest()->getParams();
3
+ if($params && array_key_exists('id', $params))
4
+ {
5
+ $unsEdqInfoMatrixFor = 'unsEdqInfoMatrixFor' . $params['id'];
6
+ Mage::getSingleton('adminhtml/session')->$unsEdqInfoMatrixFor();
7
+ }
8
+ $helper = Mage::helper('addressvalidation/Settings');
9
+ ?>
10
+ <script type="text/javascript">
11
+ //<![CDATA[
12
+ (function() {
13
+ var isUSAEnabled = Boolean(<?php echo $helper->areUSDataSetsEnabled(); ?>);
14
+ var isCANEnabled = Boolean(<?php echo $helper->isCANEnabled(); ?>);
15
+ var isGBREnabled = Boolean(<?php echo $helper->isGBREnabled(); ?>);
16
+ var isDEUEnabled = Boolean(<?php echo $helper->isDEUEnabled(); ?>);
17
+ var isIRLEnabled = Boolean(<?php echo $helper->isIRLEnabled(); ?>);
18
+
19
+ window.ExperianDataQuality = window.ExperianDataQuality || {};
20
+ window.ExperianDataQuality.DataQuality = window.ExperianDataQuality.DataQuality || {};
21
+ window.ExperianDataQuality.DataQuality.Address = window.ExperianDataQuality.DataQuality.Address || {};
22
+
23
+ window.ExperianDataQuality.DataQuality.Address.InteractionRequired = "<?php echo $this->__('We recommend:'); ?>";
24
+ window.ExperianDataQuality.DataQuality.Address.PremisesPartial = "<?php echo $this->__('Confirm your Apartment/Suite/Unit number:'); ?>";
25
+ window.ExperianDataQuality.DataQuality.Address.StreetPartial = "<?php echo $this->__('Confirm your House/Building number:'); ?>";
26
+ window.ExperianDataQuality.DataQuality.Address.AptAppend = "<?php echo $this->__('Confirm your House/Building number:'); ?>";
27
+ window.ExperianDataQuality.DataQuality.Address.Multiple = "<?php echo $this->__('Our suggested matches:'); ?>";
28
+ window.ExperianDataQuality.DataQuality.Address.None = "<?php echo $this->__('No Match'); ?>";
29
+
30
+ window.ExperianDataQuality.DataQuality.Address.EnterSelection = "<?php echo $this->__("Enter selection"); ?>";
31
+ window.ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions = "<?php echo $this->__("Please select a suggestion."); ?>";
32
+ window.ExperianDataQuality.DataQuality.Address.RefinementText = "<?php echo $this->__('Your selection covers a range of addresses. Enter your exact details:'); ?>";
33
+ window.ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage = "<?php echo $this->__("Search cancelled (too many matches)"); ?>";
34
+ window.ExperianDataQuality.DataQuality.Address.NoMatchesMessage = "<?php echo $this->__("No matches"); ?>";
35
+ window.ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage = "<?php echo $this->__("Please enter exact details."); ?>";
36
+ window.ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage = "<?php echo $this-> __("This address is outside of the range. Please try again or click Back and select the correct range."); ?>";
37
+
38
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets = [];
39
+
40
+ if(isUSAEnabled) {
41
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('US');
42
+ }
43
+
44
+ if(isCANEnabled) {
45
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('CA');
46
+ }
47
+
48
+ if(isGBREnabled) {
49
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('GB');
50
+ }
51
+
52
+ if(isDEUEnabled) {
53
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('DE');
54
+ }
55
+
56
+ if(isIRLEnabled) {
57
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('IE');
58
+ }
59
+
60
+ if(!isCANEnabled && !isUSAEnabled && !isGBREnabled && !isDEUEnabled && !isIRLEnabled) { return false; }
61
+
62
+ var existingAddresses = $('address_list').select('li');
63
+
64
+ if(existingAddresses.length > 0)
65
+ {
66
+ for (var i=0, max=existingAddresses.length; i<max; i++) {
67
+ var prefix = existingAddresses[i].readAttribute('id').replace(/[^\d.]/g, "");
68
+ var countryElement = $('_item' + prefix + 'country_id');
69
+ var postcodeElement = $('_item' + prefix + 'postcode');
70
+
71
+ edq_configureSingleLine(postcodeElement, countryElement, prefix);
72
+ }
73
+ }
74
+ edq_initializeObervations();
75
+ })();
76
+
77
+ function edq_initializeObervations(){
78
+ var addNewAddressButton = $('add_address_button');
79
+
80
+ addNewAddressButton.observe('click', function() {
81
+ var newAddress = $('address_list').select('li').last();
82
+ var prefix = newAddress.readAttribute('id').replace(/[^\d.]/g, '');
83
+ var countryElement = $('_item' + prefix + 'country_id');
84
+ var postcodeElement = $('_item' + prefix + 'postcode');
85
+
86
+ edq_configureSingleLine(postcodeElement, countryElement, prefix);
87
+ });
88
+ }
89
+
90
+ function edq_configureSingleLine(postcodeElement, countryElement, prefix) {
91
+ edq_insertSingleLineTemplate(postcodeElement, prefix);
92
+ edq_putCountryOnTop(prefix, countryElement);
93
+ edq_initializeAddressConfigurations(prefix);
94
+
95
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
96
+
97
+ countryElement.observe('change', function() {
98
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
99
+ });
100
+ }
101
+
102
+ function edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement) {
103
+ var streetElement = $('edq-street-' + prefix);
104
+ var buildingNumberElement = $('edq-building-number-' + prefix);
105
+
106
+ if(countryElement.value === 'DE')
107
+ streetElement.up('tr').insert( { 'after' : buildingNumberElement.up('tr') } );
108
+ else
109
+ buildingNumberElement.up('tr').insert( { 'after' : streetElement.up('tr') } );
110
+
111
+ }
112
+
113
+ function edq_putCountryOnTop(prefix, countryElement) {
114
+ $('_item' + prefix + 'company').up('tr').insert( { 'after' : countryElement.up('tr') } );
115
+ }
116
+
117
+ function edq_initializeAddressConfigurations(prefix) {
118
+ var dq = ExperianDataQuality.DataQuality;
119
+
120
+ var addressConfiguration = new dq.Configuration();
121
+ var addressMapping = {
122
+ 'DataSet': '_item' + prefix + 'country_id',
123
+ 'ManualEntry' : 'edq-manual-entry-' + prefix,
124
+ 'Street1': 'edq-street-' + prefix,
125
+ 'Postcode': 'edq-zip-' + prefix,
126
+ 'Town': 'edq-town-or-locality-' + prefix,
127
+ 'FindAddressButton': 'edq-find-address-button-' + prefix,
128
+ 'BuildingNumberOrName': 'edq-building-number-' + prefix,
129
+ 'UnknownPostCode': 'edq-unknown-postcode-' + prefix,
130
+ 'KnownPostCode': 'edq-known-postcode-' + prefix,
131
+ 'Suggestions': 'edq-suggestions-' + prefix,
132
+ 'BackButton': ['edq-back-button-' + prefix,
133
+ 'edq-back-button-' + prefix + '-suggestions',
134
+ 'edq-back-button-' + prefix + '-tryagain',
135
+ 'edq-back-button-' + prefix + '-next'],
136
+ 'SelectButton': 'edq-select-button-' + prefix,
137
+ 'Refinement': 'edq-refine-input-' + prefix,
138
+ 'NextButton': 'edq-next-address-button-' + prefix,
139
+ 'ErrorMessage': 'edq-error-message-' + prefix,
140
+ 'MatchType': 'edq-matchtype-' + prefix,
141
+ 'TryAgain': 'edq-try-again-button-' + prefix,
142
+ 'ChangeAddressButton' : 'edq-change-address-button-' + prefix,
143
+ 'Loader' : 'edq-loader-please-wait-' + prefix,
144
+ 'Line0' : '_item' + prefix + 'street0',
145
+ 'Line1' : '_item' + prefix + 'street1',
146
+ 'Line2' : '_item' + prefix + 'city',
147
+ 'Line3' : '_item' + prefix + 'region_id',
148
+ 'Line4' : '_item' + prefix + 'postcode'
149
+ };
150
+
151
+ createInputAndOutputMappingFor(addressMapping, addressConfiguration, prefix);
152
+
153
+ var edqAddressClient = new dq.Address.Client();
154
+ edqAddressClient.addConfiguration(addressConfiguration);
155
+ edqAddressClient.initialize();
156
+
157
+ dq.Address.Configuration.IsManualEntryAllowed = Boolean(<?php echo $helper->isManualEntryEnabled(); ?>);
158
+ dq.Address.Configuration.SearchServiceUrl = '<?php echo Mage::getUrl('adminhtml/processAdmin/searchSingleLine' , array('_secure' => true, '_current' => true)); ?>' + '?isAjax=true';
159
+ dq.Address.Configuration.RefineServiceUrl = '<?php echo Mage::getUrl('adminhtml/processAdmin/refineSingleLine', array('_secure' => true, '_current' => true)); ?>' + '?isAjax=true';
160
+ dq.Address.Configuration.GetAddressServiceUrl = '<?php echo Mage::getUrl('adminhtml/processAdmin/formatSingleLine', array('_secure' => true, '_current' => true)); ?>' + '?isAjax=true';
161
+ }
162
+
163
+
164
+ function createInputAndOutputMappingFor(elements, configuration, prefix) {
165
+ var sys = ExperianDataQuality.system;
166
+ var dq = ExperianDataQuality.DataQuality;
167
+
168
+ for (var key in elements) {
169
+ if (!elements.hasOwnProperty(key)) {
170
+ continue;
171
+ }
172
+
173
+ if(sys.isArray(elements[key])) {
174
+ var allElementExist = true;
175
+
176
+ for(var i = 0, max = elements[key].length; i < max; i++) {
177
+ var element = sys.getElementById(elements[key][i]);
178
+
179
+ if (sys.isNull(element)) {
180
+ allElementExist = false;
181
+ continue;
182
+ }
183
+ }
184
+
185
+ if(!allElementExist) {
186
+ continue;
187
+ }
188
+ } else {
189
+ var element = sys.getElementById(elements[key]);
190
+
191
+ if (sys.isNull(element)) {
192
+ continue;
193
+ }
194
+ }
195
+
196
+ if (element.tagName !== dq.HtmlTags.Label) {
197
+ configuration.addInputMapping(key, elements[key]);
198
+ }
199
+ }
200
+ configuration.addOutputMapping('_item' + prefix + 'street0', "Line0");
201
+ configuration.addOutputMapping('_item' + prefix + 'street1', "Line1");
202
+ configuration.addOutputMapping('_item' + prefix + 'city', "Line2");
203
+ configuration.addOutputMapping('_item' + prefix + 'region', "Line3");
204
+ configuration.addOutputMapping('_item' + prefix + 'region_id', "Line3");
205
+ configuration.addOutputMapping('_item' + prefix + 'postcode', "Line4");
206
+
207
+ configuration.addOutputMapping('edq-error-message-' + prefix, "ErrorMessage");
208
+ };
209
+ //]]>
210
+ </script>
app/design/frontend/base/default/layout/edqaddressvalidation.xml ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layout version="0.1.0">
3
+ <!--
4
+ Multi Shipping BEGIN
5
+ -->
6
+
7
+ <checkout_multishipping_customer_address>
8
+ <reference name="head">
9
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/json2.js</name></action>
10
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/system.js</name></action>
11
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqClient.js</name></action>
12
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqAddressClient.js</name></action>
13
+ </reference>
14
+ <reference name="content">
15
+ <block type="customer/address_edit" name="customer_address_edq_verify" template="edq/customer/verify.phtml">
16
+ <block type="customer/address_edit" output="toHtml" name="customer_onepage_edq_singleline" as="singleline" template="edq/singleline.phtml"/>
17
+ </block>
18
+ </reference>
19
+ </checkout_multishipping_customer_address>
20
+
21
+ <checkout_multishipping_register>
22
+ <reference name="head">
23
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/json2.js</name></action>
24
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/system.js</name></action>
25
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqClient.js</name></action>
26
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqAddressClient.js</name></action>
27
+ </reference>
28
+ <reference name="content">
29
+ <block type="customer/address_edit" name="customer_address_edq_verify" template="edq/customer/verify.phtml">
30
+ <block type="customer/address_edit" output="toHtml" name="customer_onepage_edq_singleline" as="singleline" template="edq/singleline.phtml"/>
31
+ </block>
32
+ </reference>
33
+ </checkout_multishipping_register>
34
+
35
+ <!--
36
+ Multi Shipping END
37
+ -->
38
+ <!--
39
+ Checkout BEGIN
40
+ -->
41
+ <checkout_onepage_index>
42
+ <reference name="head">
43
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/json2.js</name></action>
44
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/system.js</name></action>
45
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqClient.js</name></action>
46
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqAddressClient.js</name></action>
47
+ </reference>
48
+ <reference name="content">
49
+ <block type="checkout/onepage_progress" name="checkout_onepage_edq_verify" template="edq/checkout/verify.phtml">
50
+ <block type="checkout/onepage_progress" output="toHtml" name="checkpout_onepage_edq_singleline" as="singleline" template="edq/singleline.phtml"/>
51
+ </block>
52
+ </reference>
53
+ </checkout_onepage_index>
54
+
55
+ <checkout_process_verify>
56
+ <block type="checkout/onepage_progress" name="root" output="toHtml" template="edq/popup.phtml">
57
+ <block type="checkout/onepage_progress" name="edq_chechout_rightside" as="rightside" template="edq/rightside.phtml"/>
58
+ <block type="checkout/onepage_progress" name="edq_interaction" as="interaction" template="edq/interaction.phtml"/>
59
+ </block>
60
+ </checkout_process_verify>
61
+
62
+ <checkout_process_verifybilling>
63
+ <update handle="checkout_process_verify" />
64
+ </checkout_process_verifybilling>
65
+
66
+ <checkout_process_verifyshipping>
67
+ <update handle="checkout_process_verify" />
68
+ </checkout_process_verifyshipping>
69
+
70
+ <checkout_process_refinepremises>
71
+ <update handle="checkout_process_verify" />
72
+ </checkout_process_refinepremises>
73
+
74
+ <checkout_process_refinestreet>
75
+ <update handle="checkout_process_verify" />
76
+ </checkout_process_refinestreet>
77
+
78
+ <checkout_process_refine>
79
+ <update handle="checkout_process_verify" />
80
+ </checkout_process_refine>
81
+ <!--
82
+ Checkout END
83
+ -->
84
+
85
+ <!--
86
+ Customer BEGIN
87
+ -->
88
+ <customer_address_form>
89
+ <reference name="head">
90
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/json2.js</name></action>
91
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/system.js</name></action>
92
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqClient.js</name></action>
93
+ <action method="addItem"><type>skin_js</type><name>ExperianDataQuality/js/edqAddressClient.js</name></action>
94
+ </reference>
95
+ <reference name="content">
96
+ <block type="customer/address_edit" name="customer_address_edq_verify" template="edq/customer/verify.phtml">
97
+ <block type="customer/address_edit" output="toHtml" name="customer_onepage_edq_singleline" as="singleline" template="edq/singleline.phtml"/>
98
+ </block>
99
+ </reference>
100
+ </customer_address_form>
101
+
102
+ <customer_process_verifyaddress>
103
+ <block type="customer/address_edit" name="root" output="toHtml" template="edq/popup.phtml">
104
+ <block type="customer/address_edit" name="edq_customer_rightside" as="rightside" template="edq/rightside.phtml"/>
105
+ <block type="customer/address_edit" name="edq_interaction" as="interaction" template="edq/interaction.phtml"/>
106
+ </block>
107
+ </customer_process_verifyaddress>
108
+
109
+ <customer_process_refinepremises>
110
+ <update handle="customer_process_verifyaddress" />
111
+ </customer_process_refinepremises>
112
+
113
+ <customer_process_refinestreet>
114
+ <update handle="customer_process_verifyaddress" />
115
+ </customer_process_refinestreet>
116
+
117
+ <customer_process_refine>
118
+ <update handle="customer_process_verifyaddress" />
119
+ </customer_process_refine>
120
+ <!--
121
+ Customer END
122
+ -->
123
+ </layout>
app/design/frontend/base/default/layout/edqemailandphonevalidation.xml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" ?>
2
+ <layout version="0.1.0">
3
+ <!--
4
+ My Account - Account Information - Edit Account Information
5
+ -->
6
+ <customer_account_edit>
7
+ <reference name="head">
8
+ <action method="addItem"><type>skin_js</type><name>edq/js/system.js</name></action>
9
+ <action method="addItem"><type>skin_js</type><name>edq/js/edqClient.js</name></action>
10
+ <action method="addItem"><type>skin_js</type><name>edq/js/json2.js</name></action>
11
+ </reference>
12
+ <reference name="before_body_end">
13
+ <block type="core/template" name="edq_security_token" template="edq/securityToken.phtml"/>
14
+ <block type="core/template" name="edq_customer_form_emailConfigurations" template="edq/customer/form/emailConfigurations.phtml"/>
15
+ <block type="core/template" name="edq_customer_initialize" template="edq/initialize.phtml"/>
16
+ </reference>
17
+ </customer_account_edit>
18
+
19
+ <!--
20
+ My Account - Address Book - Edit Address
21
+ -->
22
+ <customer_address_form>
23
+ <reference name="head">
24
+ <action method="addItem"><type>skin_js</type><name>edq/js/system.js</name></action>
25
+ <action method="addItem"><type>skin_js</type><name>edq/js/edqClient.js</name></action>
26
+ <action method="addItem"><type>skin_js</type><name>edq/js/json2.js</name></action>
27
+ </reference>
28
+ <reference name="before_body_end">
29
+ <block type="core/template" name="edq_security_token" template="edq/securityToken.phtml"/>
30
+ <block type="core/template" name="edq_customer_address_phoneConfigurations" template="edq/customer/address/phoneConfigurations.phtml"/>
31
+ <block type="core/template" name="edq_customer_initialize" template="edq/initialize.phtml"/>
32
+ </reference>
33
+ </customer_address_form>
34
+
35
+ <!--
36
+ Checkout
37
+ -->
38
+ <checkout_onepage_index>
39
+ <reference name="head">
40
+ <action method="addItem"><type>skin_js</type><name>edq/js/system.js</name></action>
41
+ <action method="addItem"><type>skin_js</type><name>edq/js/edqClient.js</name></action>
42
+ <action method="addItem"><type>skin_js</type><name>edq/js/json2.js</name></action>
43
+ </reference>
44
+ <reference name="before_body_end">
45
+ <block type="core/template" name="edq_security_token" template="edq/securityToken.phtml"/>
46
+ <block type="core/template" name="edq_checkout_configurations" template="edq/checkout/configurations.phtml"/>
47
+ <block type="core/template" name="edq_checkout_initialize" template="edq/initialize.phtml"/>
48
+ </reference>
49
+ </checkout_onepage_index>
50
+
51
+ <!--
52
+ New customer registration
53
+ -->
54
+ <customer_account_create>
55
+ <reference name="head">
56
+ <action method="addItem"><type>skin_js</type><name>edq/js/system.js</name></action>
57
+ <action method="addItem"><type>skin_js</type><name>edq/js/edqClient.js</name></action>
58
+ <action method="addItem"><type>skin_js</type><name>edq/js/json2.js</name></action>
59
+ </reference>
60
+ <reference name="before_body_end">
61
+ <block type="core/template" name="edq_security_token" template="edq/securityToken.phtml"/>
62
+ <block type="core/template" name="edq_customer_form_emailConfigurations" template="edq/customer/form/emailConfigurations.phtml"/>
63
+ <block type="core/template" name="edq_customer_initialize" template="edq/initialize.phtml"/>
64
+ </reference>
65
+ </customer_account_create>
66
+ </layout>
app/design/frontend/base/default/template/edq/checkout/configurations.phtml ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ function createConfigurations(isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled) {
3
+ var configurations = new Array();
4
+
5
+ if(isPhoneValidationEnabled) {
6
+ if($('billing:telephone')) { configurations.push(createPhoneConfiguration('billing:telephone', isPhoneCoutryEnabled)); }
7
+ if($('billing:fax')) { configurations.push(createPhoneConfiguration('billing:fax', isPhoneCoutryEnabled)); }
8
+ if($('shipping:telephone')) { configurations.push(createPhoneConfiguration('shipping:telephone', isPhoneCoutryEnabled)); }
9
+ if($('shipping:fax')) { configurations.push(createPhoneConfiguration('shipping:fax', isPhoneCoutryEnabled)); }
10
+ }
11
+
12
+ if(isEmailValidationEnabled) {
13
+ if($('billing:email')) { configurations.push(createEmailConfiguration('billing:email')); }
14
+ }
15
+
16
+ return configurations;
17
+ }
18
+
19
+ function createPhoneConfiguration(phoneHtmlElementId, isPhoneCoutryEnabled) {
20
+ var dq = EDQ.DataQuality;
21
+
22
+ var configuration = new dq.Configuration();
23
+
24
+ configuration.type = dq.ConfigurationType.Phone;
25
+
26
+ if(isPhoneCoutryEnabled) {
27
+ configuration.addInputMapping(dq.PhoneCountry, getCountryCodeFieldId(phoneHtmlElementId));
28
+ }
29
+ configuration.addInputMapping(dq.Phone, phoneHtmlElementId);
30
+
31
+ configuration.addOutputMapping(phoneHtmlElementId, dq.Phone);
32
+ configuration.addOutputMapping(getValidationLabelId(phoneHtmlElementId), dq.ValidationMessageForLabel);
33
+ configuration.addOutputMapping(getLoaderId(phoneHtmlElementId), dq.Loader);
34
+
35
+ return configuration;
36
+ }
37
+
38
+ function createEmailConfiguration(emailHtmlElementId) {
39
+ var dq = EDQ.DataQuality;
40
+
41
+ var configuration = new dq.Configuration();
42
+
43
+ configuration.type = dq.ConfigurationType.Email;
44
+
45
+ configuration.addInputMapping(dq.Email, emailHtmlElementId);
46
+
47
+ configuration.addOutputMapping(emailHtmlElementId, dq.Email);
48
+ configuration.addOutputMapping(getSuggestionLabelId(emailHtmlElementId), dq.CorrectionsForLabel);
49
+ configuration.addOutputMapping(getValidationLabelId(emailHtmlElementId), dq.ValidationMessageForLabel);
50
+ configuration.addOutputMapping(getLoaderId(emailHtmlElementId), dq.Loader);
51
+
52
+ return configuration;
53
+ }
54
+ </script>
app/design/frontend/base/default/template/edq/checkout/verify.phtml ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ <?php
3
+ $billingPrefix = 'billing';
4
+ $shippingPrefix = 'shipping';
5
+ $helper = Mage::helper('addressvalidation/Settings');
6
+ ?>
7
+ //<![CDATA[
8
+ (function() {
9
+ var isGBREnabled = Boolean(<?php echo $helper->isGBREnabled(); ?>);
10
+ var isDEUEnabled = Boolean(<?php echo $helper->isDEUEnabled(); ?>);
11
+ var isIRLEnabled = Boolean(<?php echo $helper->isIRLEnabled(); ?>);
12
+
13
+ window.ExperianDataQuality = window.ExperianDataQuality || {};
14
+ window.ExperianDataQuality.DataQuality = window.ExperianDataQuality.DataQuality || {};
15
+ window.ExperianDataQuality.DataQuality.Address = window.ExperianDataQuality.DataQuality.Address || {};
16
+
17
+ window.ExperianDataQuality.DataQuality.Address.EnterSelection = "<?php echo $this->__("Enter selection"); ?>";
18
+ window.ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions = "<?php echo $this->__("Please select a suggestion."); ?>";
19
+ window.ExperianDataQuality.DataQuality.Address.RefinementText = "<?php echo $this->__('Your selection covers a range of addresses. Enter your exact details:'); ?>";
20
+ window.ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage = "<?php echo $this->__("Search cancelled (too many matches)"); ?>";
21
+ window.ExperianDataQuality.DataQuality.Address.NoMatchesMessage = "<?php echo $this->__("No matches"); ?>";
22
+ window.ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage = "<?php echo $this->__("Please enter exact details."); ?>";
23
+ window.ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage = "<?php echo $this-> __("This address is outside of the range. Please try again or click Back and select the correct range."); ?>";
24
+
25
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets = [];
26
+
27
+ if(isGBREnabled) {
28
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('GB');
29
+ }
30
+
31
+ if(isDEUEnabled) {
32
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('DE');
33
+ }
34
+
35
+ if(isIRLEnabled) {
36
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('IE');
37
+ }
38
+
39
+ document.getElementById("billing-buttons-container").getElementsByTagName("button")[0].onclick = qas_first_pass_billing;
40
+ document.getElementById("shipping-buttons-container").getElementsByTagName("button")[0].onclick = qas_first_pass_shipping;
41
+
42
+ initializeSignleLine(isGBREnabled, isDEUEnabled, isIRLEnabled);
43
+ })();
44
+ var isbilling = true;
45
+
46
+ var qas_showVerify = function(transport) {
47
+ if (transport && transport.responseText) {
48
+ try {
49
+ response = transport.responseText.evalJSON(true);
50
+ }
51
+ catch (e) {
52
+ response = {};
53
+ }
54
+ }
55
+
56
+ if (response.error) {
57
+ qas_close();
58
+ if(isbilling) {
59
+ billing.save();
60
+ }
61
+ else {
62
+ shipping.save();
63
+ }
64
+
65
+ return;
66
+ }
67
+
68
+ if(response.address) {
69
+ var prefix = isbilling ? '<?php echo $billingPrefix; ?>' : '<?php echo $shippingPrefix; ?>';
70
+
71
+ $(prefix + ':street1').value = response.address.street[0];
72
+ $(prefix + ':street2').value = response.address.street[1];
73
+ $(prefix + ':city').value = response.address.city;
74
+ $(prefix + ':region_id').value = response.address.region_id;
75
+ $(prefix + ':postcode').value = response.address.postcode;
76
+
77
+ qas_close();
78
+ if(isbilling) {
79
+ billing.save();
80
+ }
81
+ else {
82
+ shipping.save();
83
+ }
84
+
85
+ } else {
86
+ window.scroll(0,0);
87
+ $('qas_popup').innerHTML = "";
88
+ $('qas_popup').innerHTML = transport.responseText;
89
+ document.getElementById('qas_cover').style.display = "";
90
+ document.getElementById('qas_popup').style.display = "";
91
+ }
92
+ };
93
+
94
+ var qas_close = function() {
95
+ if(isbilling) {
96
+ billing.onComplete();
97
+ } else {
98
+ shipping.onComplete();
99
+ }
100
+ document.getElementById('qas_cover').style.display = "none";
101
+ document.getElementById('qas_popup').style.display = "none";
102
+ };
103
+
104
+ var qas_clean = function(posturl, isRefine) {
105
+ if(isRefine) {
106
+ var request = new Ajax.Request(
107
+ posturl,
108
+ {
109
+ method: 'post',
110
+ onSuccess: qas_showVerify,
111
+ onFailure: checkout.ajaxFailure.bind(checkout),
112
+ parameters: {'refinetext': $('qas_refine').value}
113
+ }
114
+ );
115
+ } else {
116
+ var request = new Ajax.Request(
117
+ posturl,
118
+ {
119
+ method: 'post',
120
+ onSuccess: qas_showVerify,
121
+ onFailure: checkout.ajaxFailure.bind(checkout)
122
+ }
123
+ );
124
+ }
125
+ };
126
+
127
+ function qas_first_pass_billing() {
128
+ isbilling = true;
129
+
130
+ if (checkout.loadWaiting !== false) return;
131
+
132
+ var validator = new Validation(this.form);
133
+ if (validator.validate()) {
134
+ checkout.setLoadWaiting('billing');
135
+
136
+ var request = new Ajax.Request(
137
+ '<?php echo Mage::getUrl('checkout/process/verifyBilling', array('_secure'=>true, '_current'=>true)); ?>',
138
+ {
139
+ method: 'post',
140
+ onSuccess: qas_showVerify,
141
+ onFailure: checkout.ajaxFailure.bind(checkout),
142
+ onComplete: function(response) {
143
+ if(response.readyState < 4 || response.status !== 200) {
144
+ return;
145
+ }
146
+ billing.onComplete();
147
+ },
148
+ parameters: Form.serialize(this.form)
149
+ });
150
+ }
151
+ };
152
+
153
+ function qas_first_pass_shipping() {
154
+ isbilling = false;
155
+
156
+ if (checkout.loadWaiting !== false) return;
157
+
158
+ var validator = new Validation(this.form);
159
+ if (validator.validate()) {
160
+ checkout.setLoadWaiting('shipping');
161
+
162
+ var request = new Ajax.Request(
163
+ '<?php echo Mage::getUrl('checkout/process/verifyShipping', array('_secure'=>true, '_current'=>true)); ?>',
164
+ {
165
+ method: 'post',
166
+ onSuccess: qas_showVerify,
167
+ onFailure: checkout.ajaxFailure.bind(checkout),
168
+ onComplete: function(response) {
169
+ if(response.readyState < 4 || response.status !== 200) {
170
+ return;
171
+ }
172
+ shipping.onComplete();
173
+ },
174
+ parameters: Form.serialize(this.form)
175
+ });
176
+ }
177
+ };
178
+
179
+ function initializeSignleLine(isGBREnabled, isDEUEnabled, isIRLEnabled) {
180
+ if(!isGBREnabled && !isDEUEnabled && !isIRLEnabled) { return false; }
181
+
182
+ var singleLineBillingTemplate = <?php
183
+ $this->getChild('singleline')->setData('prefix', $billingPrefix);
184
+ echo json_encode($this->getChildHtml('singleline', false));
185
+ ?>;
186
+
187
+ var singleLineShppingTemplate = <?php
188
+ $this->getChild('singleline')->setData('prefix', $shippingPrefix);
189
+ echo json_encode($this->getChildHtml('singleline', false));
190
+ ?>;
191
+
192
+ edq_configurationSetUp('<?php echo $billingPrefix; ?>', singleLineBillingTemplate, isGBREnabled, isDEUEnabled, isIRLEnabled);
193
+ edq_configurationSetUp('<?php echo $shippingPrefix; ?>', singleLineShppingTemplate, isGBREnabled, isDEUEnabled, isIRLEnabled);
194
+ }
195
+
196
+ function edq_configurationSetUp(prefix, template, isGBREnabled, isDEUEnabled, isIRLEnabled) {
197
+ var countryElement = $(prefix + ':country_id');
198
+
199
+ countryElement.up('li').insert( { 'after' : template } );
200
+ edq_putCountryOnTop(prefix, countryElement);
201
+ edq_singleLineSetUp(prefix, countryElement.value, isGBREnabled, isDEUEnabled, isIRLEnabled);
202
+ countryElement.observe('change', function(){ edq_singleLineSetUp(prefix, this.value, isGBREnabled, isDEUEnabled, isIRLEnabled); });
203
+ edq_initializeAddressConfigurations(prefix);
204
+
205
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
206
+
207
+ countryElement.observe('change', function() {
208
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
209
+ });
210
+ };
211
+
212
+ function edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement) {
213
+ var streetElement = $(prefix + '-edq-street');
214
+ var buildingNumberElement = $(prefix + '-edq-building-number');
215
+
216
+ if(countryElement.value === 'DE')
217
+ streetElement.up('li').insert( { 'after' : buildingNumberElement.up('li') } );
218
+ else
219
+ buildingNumberElement.up('li').insert( { 'after' : streetElement.up('li') } );
220
+ }
221
+
222
+ function edq_singleLineSetUp(prefix, dataSet, isGBREnabled, isDEUEnabled, isIRLEnabled) {
223
+ if((dataSet === 'GB' && isGBREnabled)
224
+ || (dataSet === 'DE' && isDEUEnabled)
225
+ || (dataSet === 'IE' && isIRLEnabled)) {
226
+ $(prefix + '-edq-singleline').show();
227
+ }
228
+ else {
229
+ $(prefix + '-edq-singleline').hide();
230
+ }
231
+ }
232
+
233
+ function edq_initializeAddressConfigurations(prefix) {
234
+ var dq = ExperianDataQuality.DataQuality;
235
+
236
+ var addressConfiguration = new dq.Configuration();
237
+ var addressMapping = {
238
+ 'ManualEntry': prefix + '-edq-manual-entry',
239
+ 'DataSet': prefix + ':country_id',
240
+ 'Street1': prefix + '-edq-street',
241
+ 'City': prefix + '-edq-city',
242
+ 'State': prefix + '-edq-state',
243
+ 'Postcode': prefix + '-edq-zip',
244
+ 'Town': prefix + '-edq-town-or-locality',
245
+ 'FindAddressButton': prefix + '-edq-find-address-button',
246
+ 'BuildingNumberOrName': prefix + '-edq-building-number',
247
+ 'UnknownPostCode': prefix + '-edq-unknown-postcode',
248
+ 'KnownPostCode': prefix + '-edq-known-postcode',
249
+ 'Suggestions': prefix + '-edq-suggestions',
250
+ 'BackButton': [prefix + '-edq-back-button',
251
+ prefix + '-edq-back-button-suggestions',
252
+ prefix + '-edq-back-button-tryagain',
253
+ prefix + '-edq-back-button-next'],
254
+ 'SelectButton': prefix + '-edq-select-button',
255
+ 'Refinement': prefix + '-edq-refine-input',
256
+ 'NextButton': prefix + '-edq-next-address-button',
257
+ 'ErrorMessage': prefix + '-edq-error-message',
258
+ 'TryAgain': prefix + '-edq-try-again-button',
259
+ 'ChangeAddressButton' : prefix + '-edq-change-address-button',
260
+ 'Loader' : prefix + '-loader-please-wait',
261
+ 'Line0' : prefix + ':street1',
262
+ 'Line1' : prefix + ':street2',
263
+ 'Line2' : prefix + ':city',
264
+ 'Line3' : prefix + ':region',
265
+ 'Line4' : prefix + ':postcode'
266
+ };
267
+
268
+ createInputAndOutputMappingFor(addressMapping, addressConfiguration, prefix);
269
+
270
+ var edqAddressClient = new dq.Address.Client();
271
+ edqAddressClient.addConfiguration(addressConfiguration);
272
+
273
+ edqAddressClient.initialize();
274
+
275
+ dq.Address.Configuration.IsManualEntryAllowed = Boolean(<?php echo $helper->isManualEntryEnabled(); ?>);
276
+ dq.Address.Configuration.SearchServiceUrl = '<?php echo Mage::getUrl('checkout/process/searchSingleLine', array('_secure' => true, '_current' => true)); ?>';
277
+ dq.Address.Configuration.RefineServiceUrl = '<?php echo Mage::getUrl('checkout/process/refineSingleLine', array('_secure' => true, '_current' => true)); ?>';
278
+ dq.Address.Configuration.GetAddressServiceUrl = '<?php echo Mage::getUrl('checkout/process/formatSingleLine', array('_secure' => true, '_current' => true)); ?>';
279
+ }
280
+
281
+ function createInputAndOutputMappingFor(elements, configuration, prefix) {
282
+ var sys = ExperianDataQuality.system;
283
+ var dq = ExperianDataQuality.DataQuality;
284
+
285
+ for (var key in elements) {
286
+ if (!elements.hasOwnProperty(key)) {
287
+ continue;
288
+ }
289
+
290
+ if(sys.isArray(elements[key])) {
291
+ var allElementExist = true;
292
+
293
+ for(var i = 0, max = elements[key].length; i < max; i++) {
294
+ var element = sys.getElementById(elements[key][i]);
295
+
296
+ if (sys.isNull(element)) {
297
+ allElementExist = false;
298
+ continue;
299
+ }
300
+ }
301
+
302
+ if(!allElementExist) {
303
+ continue;
304
+ }
305
+ } else {
306
+ var element = sys.getElementById(elements[key]);
307
+
308
+ if (sys.isNull(element)) {
309
+ continue;
310
+ }
311
+ }
312
+
313
+ if (element.tagName !== dq.HtmlTags.Label) {
314
+ configuration.addInputMapping(key, elements[key]);
315
+ }
316
+ }
317
+
318
+ configuration.addOutputMapping(prefix + ':street1', "Line0");
319
+ configuration.addOutputMapping(prefix + ':street2', "Line1");
320
+ configuration.addOutputMapping(prefix + ':city', "Line2");
321
+ configuration.addOutputMapping(prefix + ':region', "Line3");
322
+ configuration.addOutputMapping(prefix + ':region_id', "Line3");
323
+ configuration.addOutputMapping(prefix + ':postcode', "Line4");
324
+
325
+ configuration.addOutputMapping(prefix + '-edq-error-message', "ErrorMessage");
326
+ }
327
+
328
+ function edq_putCountryOnTop(prefix, countryElement) {
329
+ var postcode = $(prefix + ':postcode');
330
+ var street1 = $(prefix + ':street1');
331
+
332
+ if(postcode.up('li').select('select').length > 0) {
333
+ var countryListElement = new Element('li');
334
+
335
+ countryListElement.className = 'fields';
336
+ countryListElement.update(countryElement.up('div.field'));
337
+
338
+ street1.up('li').insert( { 'before' : countryListElement } );
339
+ }
340
+ }
341
+ //]]>
342
+ </script>
343
+
344
+ <style type="text/css">
345
+ div.cover
346
+ {
347
+ position: absolute;
348
+ left: 0px;
349
+ top: 0px;
350
+ width: 100%;
351
+ height: 100%;
352
+ background: #333333;
353
+ filter:alpha(Opacity=75);
354
+ opacity: 0.5;
355
+ -moz-opacity: 0.5;
356
+ -khtml-opacity: 0.5;
357
+ z-index: 999;
358
+ }
359
+
360
+ div.popup
361
+ {
362
+ left:10%;
363
+ top:20%;
364
+ padding: 0em;
365
+ width: 850px;
366
+ max-height: 425px;
367
+ position: absolute;
368
+ z-index:1000;
369
+ overflow: auto;
370
+ background: white;
371
+ }
372
+
373
+ div.qas_prompt
374
+ {
375
+ margin-bottom: 1em;
376
+ }
377
+
378
+ div#picklist td
379
+ {
380
+ padding-right: 0.7em;
381
+ }
382
+ div.popup a
383
+ {
384
+ cursor: pointer;
385
+ }
386
+ h4.error_message
387
+ {
388
+ background: #d75f07;
389
+ color: #fff;
390
+ padding: 5px;
391
+ margin-bottom: 5px;
392
+ }
393
+ div.edq_error_message
394
+ {
395
+ clear: both;
396
+ color: #eb340a;
397
+ font-size: 11px;
398
+ font-weight: bold;
399
+ line-height: 13px;
400
+ margin: 3px 0 0;
401
+ min-height: 13px;
402
+ padding-left: 17px;
403
+ }
404
+ </style>
405
+
406
+ <div style="display: none" id='qas_cover' class='cover'></div>
407
+ <div style="display: none" id='qas_popup' class='popup'></div>
app/design/frontend/base/default/template/edq/customer/address/phoneConfigurations.phtml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ function createConfigurations(isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled) {
3
+ var configurations = new Array();
4
+
5
+ if(isPhoneValidationEnabled) {
6
+ configurations.push(createPhoneConfiguration('telephone', isPhoneCoutryEnabled));
7
+ configurations.push(createPhoneConfiguration('fax', isPhoneCoutryEnabled));
8
+ }
9
+
10
+ return configurations;
11
+ }
12
+
13
+ function createPhoneConfiguration(phoneHtmlElementId, isPhoneCoutryEnabled) {
14
+ var dq = EDQ.DataQuality;
15
+
16
+ var configuration = new dq.Configuration();
17
+
18
+ configuration.type = dq.ConfigurationType.Phone;
19
+
20
+ if(isPhoneCoutryEnabled) {
21
+ configuration.addInputMapping(dq.PhoneCountry, getCountryCodeFieldId(phoneHtmlElementId));
22
+ }
23
+ configuration.addInputMapping(dq.Phone, phoneHtmlElementId);
24
+
25
+ configuration.addOutputMapping(phoneHtmlElementId, dq.Phone);
26
+ configuration.addOutputMapping(getValidationLabelId(phoneHtmlElementId), dq.ValidationMessageForLabel);
27
+ configuration.addOutputMapping(getLoaderId(phoneHtmlElementId), dq.Loader);
28
+
29
+ return configuration;
30
+ }
31
+ </script>
app/design/frontend/base/default/template/edq/customer/form/emailConfigurations.phtml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ function createConfigurations(isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled) {
3
+ var configurations = new Array();
4
+ var emailId = ($('email_address') ? 'email_address' : ($('email') ? 'email' : ''));
5
+
6
+ if(isEmailValidationEnabled && emailId !== '') {
7
+ configurations.push(createEmailConfiguration(emailId));
8
+ }
9
+
10
+ return configurations;
11
+ }
12
+
13
+ function createEmailConfiguration(emailHtmlElementId) {
14
+ var dq = EDQ.DataQuality;
15
+
16
+ var configuration = new dq.Configuration();
17
+
18
+ configuration.type = dq.ConfigurationType.Email;
19
+
20
+ configuration.addInputMapping(dq.Email, emailHtmlElementId);
21
+
22
+ configuration.addOutputMapping(emailHtmlElementId, dq.Email);
23
+ configuration.addOutputMapping(getSuggestionLabelId(emailHtmlElementId), dq.CorrectionsForLabel);
24
+ configuration.addOutputMapping(getValidationLabelId(emailHtmlElementId), dq.ValidationMessageForLabel);
25
+ configuration.addOutputMapping(getLoaderId(emailHtmlElementId), dq.Loader);
26
+
27
+ return configuration;
28
+ }
29
+ </script>
app/design/frontend/base/default/template/edq/customer/verify.phtml ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ <?php
3
+ $prefix = 'book';
4
+ $helper = Mage::helper('addressvalidation/Settings');
5
+ ?>
6
+ //<![CDATA[
7
+ (function() {
8
+ var isGBREnabled = Boolean(<?php echo $helper->isGBREnabled(); ?>);
9
+ var isDEUEnabled = Boolean(<?php echo $helper->isDEUEnabled(); ?>);
10
+ var isIRLEnabled = Boolean(<?php echo $helper->isIRLEnabled(); ?>);
11
+
12
+ window.ExperianDataQuality = window.ExperianDataQuality || {};
13
+ window.ExperianDataQuality.DataQuality = window.ExperianDataQuality.DataQuality || {};
14
+ window.ExperianDataQuality.DataQuality.Address = window.ExperianDataQuality.DataQuality.Address || {};
15
+
16
+ window.ExperianDataQuality.DataQuality.Address.EnterSelection = "<?php echo $this->__("Enter selection"); ?>";
17
+ window.ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions = "<?php echo $this->__("Please select a suggestion."); ?>";
18
+ window.ExperianDataQuality.DataQuality.Address.RefinementText = "<?php echo $this->__('Your selection covers a range of addresses. Enter your exact details:'); ?>";
19
+ window.ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage = "<?php echo $this->__("Search cancelled (too many matches)"); ?>";
20
+ window.ExperianDataQuality.DataQuality.Address.NoMatchesMessage = "<?php echo $this->__("No matches"); ?>";
21
+ window.ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage = "<?php echo $this->__("Please enter exact details."); ?>";
22
+ window.ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage = "<?php echo $this-> __("This address is outside of the range. Please try again or click Back and select the correct range."); ?>";
23
+
24
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets = [];
25
+
26
+ if(isGBREnabled) {
27
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('GB');
28
+ }
29
+
30
+ if(isDEUEnabled) {
31
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('DE');
32
+ }
33
+
34
+ if(isIRLEnabled) {
35
+ window.ExperianDataQuality.DataQuality.Address.LicensedDataSets.push('IE');
36
+ }
37
+
38
+ $$('#form-validate button')[0].observe('click', function(event) {
39
+ var validator = new Validation(this.form);
40
+ if (validator.validate()) {
41
+ var request = new Ajax.Request(
42
+ '<?php echo Mage::getUrl('customer/process/verifyAddress', array('_secure' => true, '_current' => true)); ?>',
43
+ {
44
+ method: 'post',
45
+ onSuccess: qas_showVerify,
46
+ onFailure: qas_onAjaxFailure,
47
+ parameters: Form.serialize(this.form)
48
+ });
49
+ event.preventDefault();
50
+ event.stop();
51
+ }
52
+ });
53
+
54
+ initializeSignleLine(isGBREnabled, isDEUEnabled, isIRLEnabled);
55
+ })();
56
+
57
+ var qas_clean = function(posturl, isRefine)
58
+ {
59
+ if(isRefine) {
60
+ var request = new Ajax.Request( posturl,
61
+ {
62
+ method: 'post',
63
+ onSuccess: qas_showVerify,
64
+ onFailure: qas_onAjaxFailure,
65
+ parameters: {'refinetext': $('qas_refine').value}
66
+ });
67
+ } else {
68
+ var request = new Ajax.Request( posturl,
69
+ {
70
+ method: 'post',
71
+ onSuccess: qas_showVerify,
72
+ onFailure: qas_onAjaxFailure
73
+ });
74
+ }
75
+ };
76
+
77
+ var qas_showVerify = function(transport)
78
+ {
79
+ if (transport && transport.responseText) {
80
+ try {
81
+ response = transport.responseText.evalJSON(true);
82
+ }
83
+ catch (e) {
84
+ response = {};
85
+ }
86
+ }
87
+
88
+ if (response.error) {
89
+ qas_close();
90
+ $('form-validate').submit();
91
+ return;
92
+ }
93
+
94
+ if(response.address) {
95
+ $('street_1').value = response.address.street[0];
96
+ $('street_2').value = response.address.street[1];
97
+ $('city').value = response.address.city;
98
+ $('region_id').value = response.address.region_id;
99
+ $('zip').value = response.address.postcode;
100
+
101
+ qas_close();
102
+
103
+ $('form-validate').submit();
104
+ } else {
105
+ window.scroll(0,0);
106
+ $('qas_popup').innerHTML = "";
107
+ $('qas_popup').innerHTML = transport.responseText;
108
+ document.getElementById('qas_cover').style.display = "";
109
+ document.getElementById('qas_popup').style.display = "";
110
+ }
111
+ };
112
+
113
+ var qas_onAjaxFailure = function() {
114
+ qas_close();
115
+ $('form-validate').submit();
116
+ };
117
+
118
+ var qas_close = function() {
119
+ document.getElementById('qas_cover').style.display = "none";
120
+ document.getElementById('qas_popup').style.display = "none";
121
+ };
122
+
123
+ function initializeSignleLine(isGBREnabled, isDEUEnabled, isIRLEnabled) {
124
+ if(!isGBREnabled && !isDEUEnabled && !isIRLEnabled) { return false; }
125
+
126
+ var prefix = '<?php echo $prefix; ?>';
127
+ var countryElement = $('country');
128
+ var singleLineTemplate = <?php
129
+ $this->getChild('singleline')->setData('prefix', $prefix);
130
+ echo json_encode($this->getChildHtml('singleline', false));
131
+ ?>;
132
+
133
+ countryElement.up('li').insert( { 'after' : singleLineTemplate } );
134
+ edq_putCountryOnTop(countryElement);
135
+ edq_singleLineSetUp(prefix, countryElement.value, isGBREnabled, isDEUEnabled, isIRLEnabled);
136
+ countryElement.observe('change', function(){ edq_singleLineSetUp(prefix, this.value, isGBREnabled, isDEUEnabled, isIRLEnabled); });
137
+ edq_initializeAddressConfigurations(prefix);
138
+
139
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
140
+
141
+ countryElement.observe('change', function() {
142
+ edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement);
143
+ });
144
+ }
145
+
146
+ function edq_singleLineSetUp(prefix, dataSet, isGBREnabled, isDEUEnabled, isIRLEnabled) {
147
+ if((dataSet === 'GB' && isGBREnabled)
148
+ || (dataSet === 'DE' && isDEUEnabled)
149
+ || (dataSet === 'IE' && isIRLEnabled)) {
150
+ $(prefix + '-edq-singleline').show();
151
+ }
152
+ else {
153
+ $(prefix + '-edq-singleline').hide();
154
+ }
155
+ }
156
+
157
+ function edq_toggleBuildingNumberOrNameAndStreet(prefix, countryElement) {
158
+ var streetElement = $(prefix + '-edq-street');
159
+ var buildingNumberElement = $(prefix + '-edq-building-number');
160
+
161
+ if(countryElement.value === 'DE')
162
+ streetElement.up('li').insert( { 'after' : buildingNumberElement.up('li') } );
163
+ else
164
+ buildingNumberElement.up('li').insert( { 'after' : streetElement.up('li') } );
165
+ }
166
+
167
+ function edq_initializeAddressConfigurations(prefix) {
168
+ var dq = ExperianDataQuality.DataQuality;
169
+
170
+ var addressConfiguration = new dq.Configuration();
171
+ var addressMapping = {
172
+ 'ManualEntry': prefix + '-edq-manual-entry',
173
+ 'DataSet': 'country',
174
+ 'Street1': prefix + '-edq-street',
175
+ 'City': prefix + '-edq-city',
176
+ 'State': prefix + '-edq-state',
177
+ 'Postcode': prefix + '-edq-zip',
178
+ 'Town': prefix + '-edq-town-or-locality',
179
+ 'FindAddressButton': prefix + '-edq-find-address-button',
180
+ 'BuildingNumberOrName': prefix + '-edq-building-number',
181
+ 'UnknownPostCode': prefix + '-edq-unknown-postcode',
182
+ 'KnownPostCode': prefix + '-edq-known-postcode',
183
+ 'Suggestions': prefix + '-edq-suggestions',
184
+ 'BackButton': [prefix + '-edq-back-button',
185
+ prefix + '-edq-back-button-suggestions',
186
+ prefix + '-edq-back-button-tryagain',
187
+ prefix + '-edq-back-button-next'],
188
+ 'SelectButton': prefix + '-edq-select-button',
189
+ 'Refinement': prefix + '-edq-refine-input',
190
+ 'NextButton': prefix + '-edq-next-address-button',
191
+ 'ErrorMessage': prefix + '-edq-error-message',
192
+ 'TryAgain': prefix + '-edq-try-again-button',
193
+ 'ChangeAddressButton' : prefix + '-edq-change-address-button',
194
+ 'Loader' : prefix + '-loader-please-wait',
195
+ 'Line0' : 'street_1',
196
+ 'Line1' : 'street_2',
197
+ 'Line2' : 'city',
198
+ 'Line3' : 'region',
199
+ 'Line4' : 'zip'
200
+ };
201
+
202
+ createInputAndOutputMappingFor(addressMapping, addressConfiguration, prefix);
203
+
204
+ var edqAddressClient = new dq.Address.Client();
205
+ edqAddressClient.addConfiguration(addressConfiguration);
206
+ edqAddressClient.initialize();
207
+
208
+ dq.Address.Configuration.IsManualEntryAllowed = Boolean(<?php echo $helper->isManualEntryEnabled(); ?>);
209
+ dq.Address.Configuration.SearchServiceUrl = '<?php echo Mage::getUrl('customer/process/searchSingleLine', array('_secure' => true, '_current' => true)); ?>';
210
+ dq.Address.Configuration.RefineServiceUrl = '<?php echo Mage::getUrl('customer/process/refineSingleLine', array('_secure' => true, '_current' => true)); ?>';
211
+ dq.Address.Configuration.GetAddressServiceUrl = '<?php echo Mage::getUrl('customer/process/formatSingleLine', array('_secure' => true, '_current' => true)); ?>';
212
+ }
213
+
214
+ function createInputAndOutputMappingFor(elements, configuration, prefix) {
215
+ var sys = ExperianDataQuality.system;
216
+ var dq = ExperianDataQuality.DataQuality;
217
+
218
+ for (var key in elements) {
219
+ if (!elements.hasOwnProperty(key)) {
220
+ continue;
221
+ }
222
+
223
+ if(sys.isArray(elements[key])) {
224
+ var allElementExist = true;
225
+
226
+ for(var i = 0, max = elements[key].length; i < max; i++) {
227
+ var element = sys.getElementById(elements[key][i]);
228
+
229
+ if (sys.isNull(element)) {
230
+ allElementExist = false;
231
+ continue;
232
+ }
233
+ }
234
+
235
+ if(!allElementExist) {
236
+ continue;
237
+ }
238
+ } else {
239
+ var element = sys.getElementById(elements[key]);
240
+
241
+ if (sys.isNull(element)) {
242
+ continue;
243
+ }
244
+ }
245
+
246
+ if (element.tagName !== dq.HtmlTags.Label) {
247
+ configuration.addInputMapping(key, elements[key]);
248
+ }
249
+ }
250
+
251
+ configuration.addOutputMapping('street_1', "Line0");
252
+ configuration.addOutputMapping('street_2', "Line1");
253
+ configuration.addOutputMapping('city', "Line2");
254
+ configuration.addOutputMapping('region', "Line3");
255
+ configuration.addOutputMapping('region_id', "Line3");
256
+ configuration.addOutputMapping('zip', "Line4");
257
+
258
+ configuration.addOutputMapping(prefix + '-edq-error-message', "ErrorMessage");
259
+ };
260
+
261
+ function edq_putCountryOnTop(countryElement) {
262
+ var postcode = $('zip');
263
+ var street1 = $('street_1');
264
+
265
+ if(postcode.up('li').select('select').length > 0) {
266
+ var countryListElement = new Element('li');
267
+
268
+ countryListElement.className = 'fields';
269
+ countryListElement.update(countryElement.up('div.field'));
270
+
271
+ street1.up('li').insert( { 'before' : countryListElement } );
272
+ }
273
+ }
274
+
275
+ var qas_putCountryOnTop = function() {
276
+ if($('zip').up('li').select('select').length > 0) {
277
+ var countryListElement = new Element('li');
278
+
279
+ countryListElement.className = 'fields';
280
+ countryListElement.update($('country').up('div.field'));
281
+
282
+ $('street_1').up('li').insert( { 'before' : countryListElement } );
283
+ }
284
+ };
285
+ //]]>
286
+ </script>
287
+
288
+ <style type="text/css">
289
+ div.cover
290
+ {
291
+ position: absolute;
292
+ left: 0px;
293
+ top: 0px;
294
+ width: 100%;
295
+ height: 100%;
296
+ background: #333333;
297
+ filter:alpha(Opacity=75);
298
+ opacity: 0.5;
299
+ -moz-opacity: 0.5;
300
+ -khtml-opacity: 0.5;
301
+ z-index: 999;
302
+ }
303
+
304
+ div.popup
305
+ {
306
+ left:10%;
307
+ top:20%;
308
+ padding: 0em;
309
+ width: 850px;
310
+ max-height: 425px;
311
+ position: absolute;
312
+ z-index:1000;
313
+ overflow: auto;
314
+ background: white;
315
+ }
316
+
317
+ div.qas_prompt
318
+ {
319
+ margin-bottom: 1em;
320
+ }
321
+
322
+ div#picklist td
323
+ {
324
+ padding-right: 0.7em;
325
+ }
326
+ div.popup a
327
+ {
328
+ cursor: pointer;
329
+ }
330
+
331
+ h4.error_message
332
+ {
333
+ background: #d75f07;
334
+ color: #fff;
335
+ padding: 5px;
336
+ }
337
+ div.edq_error_message
338
+ {
339
+ clear: both;
340
+ color: #eb340a;
341
+ font-size: 11px;
342
+ font-weight: bold;
343
+ line-height: 13px;
344
+ margin: 3px 0 0;
345
+ min-height: 13px;
346
+ padding-left: 17px;
347
+ }
348
+ </style>
349
+
350
+ <div style="display: none" id='qas_cover' class='cover'></div>
351
+ <div style="display: none" id='qas_popup' class='popup'></div>
app/design/frontend/base/default/template/edq/initialize.phtml ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ <?php
3
+ $helper = Mage::helper('edq_emailandphonevalidation');
4
+ $phoneValidateUrl = Mage::getUrl('edq/validation/validatePhone');
5
+ $emailValidateUrl = Mage::getUrl('edq/validation/validateEmail');
6
+ $loaderLogoUrl = $this->getSkinUrl('images/opc-ajax-loader.gif');
7
+ $isModuleEnable = Mage::helper('core')->isModuleOutputEnabled('EDQ_EmailAndPhoneValidation');
8
+ ?>
9
+ (function () {
10
+ var isModuleEnable = Boolean(<?php echo $isModuleEnable; ?>);
11
+ if(!isModuleEnable) { return false; }
12
+
13
+ var isPhoneValidationEnabled = Boolean(<?php echo $helper->isPhoneValidateEnabled(); ?>);
14
+ var isEmailValidationEnabled = Boolean(<?php echo $helper->isEmailValidateEnabled(); ?>);
15
+ var isPhoneCoutryEnabled = Boolean(<?php echo $helper->isPhoneCountrySelectionEnabled(); ?>);
16
+
17
+ if(!isPhoneValidationEnabled && !isEmailValidationEnabled) { return false; }
18
+
19
+ var configurations = createConfigurations(isPhoneValidationEnabled, isEmailValidationEnabled, isPhoneCoutryEnabled);
20
+
21
+ var dq = new EDQ.DataQuality.Client(configurations,
22
+ {
23
+ phoneUrl: '<?php echo $phoneValidateUrl ?>',
24
+ emailUrl: '<?php echo $emailValidateUrl ?>',
25
+ token: ($('session-security-token') ? $F('session-security-token') : ''),
26
+ defaultCountry: '<?php echo $helper->getPhoneDefaultCountry() ?>'
27
+ });
28
+
29
+ dq.initialize();
30
+ })();
31
+
32
+ function getCountryCodeFieldId(id) {
33
+ var countryCodeFieldId = id + '-areacode';
34
+
35
+ if(!$(countryCodeFieldId)) {
36
+ insertCoutryCodeDropDown(countryCodeFieldId, id);
37
+ }
38
+
39
+ return countryCodeFieldId;
40
+ }
41
+
42
+ function insertCoutryCodeDropDown(id, anchor) {
43
+ var currentFieldWidth = $(anchor).getStyle('width');
44
+ var newFieldWidth = stripNumericFromString(currentFieldWidth) - 65;
45
+
46
+ $(anchor).insert( { 'before' : getCountryPhoneCodesHTML(id) } );
47
+ $(anchor).setStyle( { width : newFieldWidth + 'px' } );
48
+ $(id).value = '<?php echo $helper->getPhoneDefaultCountry() ?>';
49
+ }
50
+
51
+ function getCountryPhoneCodesHTML(id) {
52
+ var html = "<select id=" + id + " name=" + id + " style='float:left; width:60px; margin-right:5px;'>";
53
+ html += "<option value='+1'><?php echo $this->__('USA') ?></option>";
54
+ html += "<option value='+33'><?php echo $this->__('FRA') ?></option>";
55
+ html += "<option value='+61'><?php echo $this->__('AUS') ?></option>";
56
+ html += "<option value='+44'><?php echo $this->__('GBR') ?></option>";
57
+ html += "</select>";
58
+ return html;
59
+ }
60
+
61
+ function getValidationLabelId(id) {
62
+ var validationLabelId = id + '-validation-label';
63
+ if(!$(validationLabelId)) {
64
+ insertValidationLabel(validationLabelId, id);
65
+ }
66
+ return validationLabelId;
67
+ }
68
+
69
+ function insertValidationLabel(id, anchor) {
70
+ var fieldWidth = $(anchor).getStyle('width');
71
+ $(anchor).insert( { 'after' : getValidationLabelHTML(id) } );
72
+ $(id).setStyle({ width : fieldWidth });
73
+ $(id).setStyle({'display' : 'none' });
74
+ $(id).setStyle({'text-align' : 'left' });
75
+ }
76
+
77
+ function getValidationLabelHTML(id) {
78
+ return "<label id=" + id + " value=''></label><br />";
79
+ }
80
+
81
+ function getLoaderId(id) {
82
+ var loaderId = id + '-loader';
83
+ if(!$(loaderId)) {
84
+ insertLoaderHTML(loaderId, id);
85
+ }
86
+ return loaderId;
87
+ }
88
+
89
+ function insertLoaderHTML(id, anchor) {
90
+ $(anchor).insert( { 'after' : getLoaderHTML(id) } );
91
+ }
92
+
93
+ function getLoaderHTML(id) {
94
+ var html = "<div style='clear:both;'></div>";
95
+ html += "<span id=" + id + " style='display:none; width:130px; float:left;'>";
96
+ html += "<img src='<?php echo $loaderLogoUrl ?>' alt='<?php echo $this->__('Loading...') ?>' title='<?php echo $this->__('Loading...') ?>'/> <?php echo $this->__('Loading...') ?>";
97
+ html += '</span>';
98
+ return html;
99
+ }
100
+
101
+ function getSuggestionLabelId(id) {
102
+ var suggestionLabelId = id + '-suggestion-label';
103
+ if(!$(suggestionLabelId)) {
104
+ insertValidationLabel(suggestionLabelId, id);
105
+ }
106
+ return suggestionLabelId;
107
+ }
108
+
109
+ function insertSuggestionLabel(id, anchor) {
110
+ var fieldWidth = $(anchor).getStyle('width');
111
+ $(anchor).insert( { 'after' : getSuggestionLabelHTML(id) } );
112
+ $(id).setStyle({ width : fieldWidth });
113
+ $(id).setStyle({'display' : 'none' });
114
+ $(id).setStyle({'text-align' : 'left' });
115
+ }
116
+
117
+ function getSuggestionLabelHTML(id) {
118
+ return "<label id=" + id + " value=''></label>";
119
+ }
120
+
121
+ function stripNumericFromString(str) {
122
+ return parseInt(str.replace(/[^\d.]/g, ""));
123
+ }
124
+ </script>
app/design/frontend/base/default/template/edq/interaction.phtml ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $helper = Mage::helper('addressvalidation/Settings');
3
+ $searchResult = Mage::getSingleton('core/session')->getSearchResult();
4
+ $isCheckOut = Mage::getSingleton('core/session')->getIsCheckout();
5
+ $isInformationInvalid = Mage::getSingleton('core/session')->getInvalidInfo();
6
+
7
+ $routeToController = $isCheckOut ? 'checkout' : 'customer';
8
+
9
+ if ($searchResult['matchType'] === 'InteractionRequired')
10
+ {
11
+ ?>
12
+ <form action="" id="qas_inter_accept">
13
+ <?php
14
+ $key = 'Line';
15
+ $numberOfLines = $helper->getNumberOfInteraotionRequiredDisplayLines();
16
+ for ($i = 0; $i < $numberOfLines; $i++)
17
+ {
18
+ $addressItem = $searchResult['cleanAddress'][$key . $i];
19
+ if($i == 3)
20
+ {
21
+ $region = Mage::getModel('directory/region')->load($addressItem);
22
+ echo $region->getName();
23
+ }
24
+ else
25
+ {
26
+ echo $addressItem;
27
+ }
28
+ echo ($addressItem !== "" ? "<br />" : "");
29
+ }
30
+ ?>
31
+ <br />
32
+ <button type="button" title="<?php echo $this->__('Use suggested address'); ?>" class="button" onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/accept', array('_secure'=>true, '_current'=>true)); ?>', false)">
33
+ <span><span><?php echo $this->__('Use suggested address'); ?></span></span>
34
+ </button>
35
+ </form>
36
+ <?php
37
+ }
38
+ else if ($searchResult['matchType'] === 'PremisesPartial')
39
+ {
40
+ ?>
41
+ <form action="" id='qas_premise_refine'>
42
+ <?php if($isInformationInvalid) { ?>
43
+ <h4 class="error_message"><?php echo $this->__('Submitted information is invalid'); ?></h4>
44
+ <?php } ?>
45
+ <input type='text' class='input-text' id='qas_refine' name='refinetext' />
46
+ <button type="button" title="<?php echo $this->__('Confirm number'); ?>" class="button" onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/refinePremises', array('_secure'=>true, '_current'=>true)); ?>', true)">
47
+ <span><span><?php echo $this->__('Confirm number'); ?></span></span>
48
+ </button>
49
+ </form>
50
+ <br /><br />
51
+ <?php
52
+ displayPartialPicklist($searchResult['picklist'], $this, $routeToController);
53
+ }
54
+ else if ($searchResult['matchType'] === 'StreetPartial') {
55
+ ?>
56
+ <form action="" id="qas_street_refine">
57
+ <?php if($isInformationInvalid) { ?>
58
+ <h4 class="error_message"><?php echo $this->__('Submitted information is invalid'); ?></h4>
59
+ <?php } ?>
60
+ <input type='text' class='input-text' id="qas_refine" name='refinetext' />
61
+ <button type="button" title="<?php echo $this->__('Confirm number'); ?>" class="button" onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/refineStreet', array('_secure'=>true, '_current'=>true)); ?>', true)">
62
+ <span><span><?php echo $this->__('Confirm number'); ?></span></span>
63
+ </button>
64
+ </form>
65
+ <br /><br />
66
+ <?php
67
+ displayPartialPicklist($searchResult['picklist'], $this, $routeToController);
68
+ }
69
+ else if ($searchResult['matchType'] === 'Multiple')
70
+ {
71
+ displayMultiplePicklist($searchResult['picklist'], $routeToController);
72
+ }
73
+ else if ($searchResult['matchType'] === 'None')
74
+ {
75
+ ?>
76
+ <h1><?php echo $this->__('Sorry, We could not find your address'); ?></h1>
77
+ <?php
78
+ }
79
+ else if ($searchResult['matchType'] === 'DPVPartial')
80
+ {
81
+ ?>
82
+ <form action="" id="qas_dpv_refine">
83
+ <input type='text' class='input-text' id="qas_refine" name='refinetext' />
84
+ <button type="button" title="<?php echo $this->__('Confirm number') ?>" class="button" onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/refineStreet', array('_secure'=>true, '_current'=>true)); ?>', true)">
85
+ <span><span><?php echo $this->__('Confirm number'); ?></span></span>
86
+ </button>
87
+ </form>
88
+ <?php
89
+ }
90
+ else if($searchResult['matchType'] === 'AptAppend')
91
+ {
92
+ ?>
93
+ <form action="" id="qas_apt_add">
94
+ <?php if($isInformationInvalid) { ?>
95
+ <h4 class="error_message"><?php echo $this->__('Submitted information is invalid'); ?></h4>
96
+ <?php } ?>
97
+ <input type='text' class='input-text' id="qas_refine" name='refinetext' />
98
+ <button type="button" title="<?php echo $this->__('Confirm number'); ?>" class="button" onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/aptAdd', array('_secure'=>true, '_current'=>true)); ?>', true)">
99
+ <span><span><?php echo $this->__('Confirm number'); ?></span></span>
100
+ </button>
101
+ <br />
102
+ <a onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/accept', array('_secure'=>true, '_current'=>true)); ?>', false)"><?php echo $this->__('No apt number'); ?></a>
103
+ </form>
104
+ <?php
105
+ }
106
+
107
+ function displayPartialPicklist($picklist, $context, $route)
108
+ {
109
+ ?>
110
+ <a href='#' onclick="Effect.toggle('picklist', 'slide', { duration: 1.0 }); return false;"><b><?php echo $context->__('Show all potential matches'); ?></b></a>
111
+ <br />
112
+ <div id='picklist' style="display:none;">
113
+ <table>
114
+ <?php
115
+ foreach($picklist as $item) {
116
+ if($item['fulladdress']) {
117
+ ?>
118
+ <tr>
119
+ <td NOWRAP>
120
+ <a onclick="qas_clean('<?php echo Mage::getUrl($route . '/process/format', array('_secure'=>true, '_current'=>true, 'moniker'=>$item['moniker'])); ?>')">
121
+ <?php echo $item['addresstext']; ?>
122
+ </a>
123
+ </td>
124
+ <td NOWRAP><?php echo $item['postcode']; ?></td>
125
+ </tr>
126
+ <?php
127
+ } else {
128
+ ?>
129
+ <tr>
130
+ <td NOWRAP><?php echo $item['addresstext']; ?></td>
131
+ <td NOWRAP><?php echo $item['postcode']; ?></td>
132
+ </tr>
133
+ <?php
134
+ }
135
+ }
136
+ ?>
137
+ </table>
138
+ </div>
139
+ <?php
140
+ }
141
+
142
+ function displayMultiplePicklist($picklist, $route)
143
+ {
144
+ ?>
145
+ <div id='picklist'>
146
+ <table>
147
+ <?php
148
+ foreach($picklist as $item) {
149
+ if($item['fulladdress']) {
150
+ ?>
151
+ <tr>
152
+ <td NOWRAP>
153
+ <a onclick="qas_clean('<?php echo Mage::getUrl($route . '/process/format', array('_secure'=>true, '_current'=>true, 'moniker'=>$item['moniker'])); ?>')">
154
+ <?php echo $item['addresstext']; ?>
155
+ </a>
156
+ </td>
157
+ <td NOWRAP><?php echo $item['postcode']; ?></td>
158
+ </tr>
159
+ <?php
160
+ } else {
161
+ ?>
162
+ <tr>
163
+ <td NOWRAP>
164
+ <a onclick="qas_clean('<?php echo Mage::getUrl($route . '/process/refine', array('_secure'=>true, '_current'=>true, 'moniker'=>$item['moniker'])); ?>')">
165
+ <?php echo $item['addresstext']; ?>
166
+ </a>
167
+ </td>
168
+ <td NOWRAP><?php echo $item['postcode']; ?></td>
169
+ </tr>
170
+ <?php
171
+ }
172
+ }
173
+ ?>
174
+ </table>
175
+ </div>
176
+ <?php
177
+ }
178
+ ?>
app/design/frontend/base/default/template/edq/popup.phtml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $QAS_HEAD = array
3
+ (
4
+ "InteractionRequired" => 'We think that your address may be incorrect or incomplete. To proceed, please choose one of the options below.',
5
+ "PremisesPartial" => 'Sorry, we think your apartment/suite/unit is missing or wrong. To proceed, please enter your apartment/suite/unit or use your address as entered.',
6
+ "StreetPartial" => 'Sorry, we don\'t recognize your house or building number. To proceed, please check and choose from one of the options below.',
7
+ "DPVPartial" => 'Sorry, we don\'t recognize your house or building number. To proceed, please check and choose from one of the options below.',
8
+ "AptAppend" => 'Sorry, we think your apartment/suite/unit is missing or wrong. To proceed, please enter your apartment/suite/unit or use your address as entered.',
9
+ "Multiple" => 'We found more than one match for your address. To proceed, please choose one of the options below.',
10
+ "None" => 'Sorry, we could not find a match for your address. To proceed, please choose one of the options below.'
11
+ );
12
+
13
+ $QAS_PROMPT = array
14
+ (
15
+ "InteractionRequired" => 'We recommend:',
16
+ "PremisesPartial" => 'Confirm your Apartment/Suite/Unit number:',
17
+ "StreetPartial" => 'Confirm your House/Building number:',
18
+ "AptAppend" => 'Confirm your House/Building number:',
19
+ "Multiple" => 'Our suggested matches:',
20
+ "None" => 'No Match'
21
+ );
22
+
23
+ $searchResult = Mage::getSingleton('core/session')->getSearchResult();
24
+ ?>
25
+
26
+ <div class="dashboard">
27
+ <div class="box-account box-info info-box">
28
+ <div class="box-head">
29
+ <h2 class="sub-title"><?php echo $this->__('Verify Your Address Details'); ?></h2>
30
+ </div>
31
+ <div class='notice-msg demo-notice qas_prompt'>
32
+ <?php echo $this->__($QAS_HEAD[$searchResult['matchType']]); ?>
33
+ </div>
34
+ <div class="col2-set">
35
+ <div class="col-1 col-wide wide">
36
+ <div class="box">
37
+ <div class="box-title">
38
+ <h3><?php echo $this->__($QAS_PROMPT[$searchResult['matchType']]); ?></h3>
39
+ </div>
40
+ <div class="box-content">
41
+ <?php echo $this->getChildHtml('interaction') ?>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div class="col-2 col-narrow narrow">
46
+ <?php echo $this->getChildHtml('rightside') ?>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
app/design/frontend/base/default/template/edq/rightside.phtml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $data = Mage::getSingleton('core/session')->getCustomerData();
3
+ $isBilling = Mage::getSingleton('core/session')->getIsBilling();
4
+ $isCheckout = Mage::getSingleton('core/session')->getIsCheckout();
5
+ $routeToController = $isCheckout ? 'checkout' : 'customer';
6
+
7
+ function getRegion($country, $regionId)
8
+ {
9
+ $regions = json_decode(Mage::helper('directory')->getRegionJson());
10
+
11
+ foreach ($regions->$country as $key => $value)
12
+ {
13
+ if($key === $regionId)
14
+ {
15
+ return $value->name;
16
+ }
17
+ }
18
+ }
19
+ ?>
20
+
21
+ <div class="box">
22
+ <div class="box-title">
23
+ <h3>
24
+ <?php echo $this->__('You Entered:') ?>
25
+ </h3>
26
+ <a onclick="qas_close()">
27
+ <?php echo $this->__('Edit'); ?>
28
+ </a>
29
+ </div>
30
+ <div class="box-content">
31
+ <address>
32
+ <?php
33
+ if(isset($data['address']['firstname']) && isset($data['address']['lastname']))
34
+ {
35
+ echo $data['address']['firstname'] . ' ' . $data['address']['lastname'];
36
+ }
37
+ ?>
38
+ <br>
39
+ <?php
40
+ if(isset($data['address']['street']) && isset($data['address']['street'][0]))
41
+ {
42
+ echo $data['address']['street'][0];
43
+ }
44
+ ?>
45
+ <br>
46
+ <?php
47
+ if(isset($data['address']['city']) && isset($data['address']['country_id']) && isset($data['address']['region_id']) && isset($data['address']['postcode']))
48
+ {
49
+ echo $data['address']['city'] . ', ' . getRegion($data['address']['country_id'], $data['address']['region_id']) . ', ' . $data['address']['postcode'];
50
+ }
51
+ ?>
52
+ <br>
53
+ <?php
54
+ if(isset($data['address']['country_id']))
55
+ {
56
+ echo $data['address']['country_id'] === 'US' ? ' United States' : 'Canada';
57
+ }
58
+ ?>
59
+ <br>
60
+ <?php
61
+ if(isset($data['address']['telephone']) && strlen($data['address']['telephone']) > 0)
62
+ {
63
+ echo 'T: ' . $data['address']['telephone'];
64
+ }
65
+ ?>
66
+ <br>
67
+ <?php
68
+ if(isset($data['address']['fax']) && strlen($data['address']['fax']) > 0)
69
+ {
70
+ echo 'F: ' . $data['address']['fax'];
71
+ }
72
+ ?>
73
+ </address>
74
+ <br />
75
+ <button type="button"
76
+ title="<?php echo $this->__('Use Address As Entered *'); ?>"
77
+ class="button"
78
+ onclick="qas_clean('<?php echo Mage::getUrl($routeToController . '/process/original', array('_secure' => true, '_current' => true)); ?>', false)">
79
+ <span>
80
+ <span>
81
+ <?php echo $this->__('Use Address As Entered *'); ?>
82
+ </span>
83
+ </span>
84
+ </button>
85
+ <p class="notice">
86
+ <?php echo $this->__('* Your address may be undeliverable'); ?>
87
+ </p>
88
+ </div>
89
+ </div>
app/design/frontend/base/default/template/edq/securityToken.phtml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $helper = Mage::helper('edq_emailandphonevalidation');
3
+ $token = '';
4
+
5
+ if(!$helper->isSessionSecurityEnabled()) {
6
+ return;
7
+ }
8
+
9
+ $tokenAndTimeStamp = Mage::getSingleton('core/session', array('name' => 'frontend'))->getTokenAndTimeStamp();
10
+ $createNewToken = false;
11
+
12
+ if(isset($tokenAndTimeStamp)) {
13
+ $tokenParts = explode('|', $tokenAndTimeStamp);
14
+ $tokenExparationDate = date('Y-m-d H:i:s', strtotime('+'.$helper->getSessionSecurityTokenLifeTime().' minutes', strtotime($tokenParts[1])));
15
+ if($tokenExparationDate < $helper->getCurrentDateTime()) {
16
+ $createNewToken = true;
17
+ }
18
+ $token = $tokenParts[0];
19
+ } else {
20
+ $createNewToken = true;
21
+ }
22
+
23
+ if($createNewToken) {
24
+ if(function_exists('com_create_guid')) {
25
+ $token = com_create_guid();
26
+ } else {
27
+ $charid = strtoupper(md5(uniqid(rand(), true)));
28
+ $hyphen = chr(45);// '-'
29
+ $token = substr($charid, 0, 8).$hyphen
30
+ .substr($charid, 8, 4).$hyphen
31
+ .substr($charid,12, 4).$hyphen
32
+ .substr($charid,16, 4).$hyphen
33
+ .substr($charid,20,12);
34
+ }
35
+ }
36
+
37
+ $tokenAndTimeStamp = $token . '|' . $helper->getCurrentDateTime();
38
+ Mage::getSingleton('core/session', array('name' => 'frontend'))->setTokenAndTimeStamp($tokenAndTimeStamp);
39
+ ?>
40
+ <input type="hidden" name="token" id="session-security-token" value="<?php echo $token ?>" />
app/design/frontend/base/default/template/edq/singleline.phtml ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $prefix = $this->getPrefix();
3
+ ?>
4
+ <ul class='form-list' id=<?php echo $prefix; ?>-edq-singleline >
5
+
6
+ <li class='fields edq_wrapper' style='display: none;'>
7
+ <div class='field'>
8
+ <label for=<?php echo $prefix; ?>-edq-building-number><?php echo $this->__('Building Number or Name'); ?></label>
9
+ <div class='input-box'>
10
+ <input id=<?php echo $prefix; ?>-edq-building-number type='text' class='input-text' tabindex="10" size="40"/>
11
+ </div>
12
+ </div>
13
+ </li>
14
+ <!-- End of row-->
15
+
16
+ <li class='fields edq_wrapper' style='display: none;'>
17
+ <div class='field'>
18
+ <label for=<?php echo $prefix; ?>-edq-street><?php echo $this->__('Street'); ?></label>
19
+ <div class='input-box'>
20
+ <input id=<?php echo $prefix; ?>-edq-street type='text' class='input-text' tabindex="20" size="40" />
21
+ </div>
22
+ </div>
23
+ </li>
24
+ <!-- End of row-->
25
+
26
+ <li class='fields edq_wrapper' style='display: none;'>
27
+ <div class='field'>
28
+ <label for=<?php echo $prefix; ?>-edq-town-or-locality><?php echo $this->__('Town'); ?></label>
29
+ <div class='input-box'>
30
+ <input id=<?php echo $prefix; ?>-edq-town-or-locality type='text' class='input-text' tabindex="30" size="40"/>
31
+ </div>
32
+ </div>
33
+ </li>
34
+ <!-- End of row-->
35
+
36
+ <li class='fields edq_wrapper' style='display: none;'>
37
+ <div class='field'>
38
+ <label for=<?php echo $prefix; ?>-edq-zip><?php echo $this->__('Postcode'); ?></label>
39
+ <div class='input-box'>
40
+ <input id=<?php echo $prefix; ?>-edq-zip type='text' class='input-text' tabindex="40" size="10"/>
41
+ </div>
42
+ </div>
43
+ </li>
44
+ <!-- End of row-->
45
+
46
+ <li class='fields edq_wrapper' style='display: none;'>
47
+ <div class='field'>
48
+ <label for=<?php echo $prefix; ?>-edq-refine-input><?php echo $this->__('Your selection covers a range of addresses. Enter your exact details: '); ?></label>
49
+ <div class='input-box'>
50
+ <input id=<?php echo $prefix; ?>-edq-refine-input type='text' class='input-text' tabindex="50" size="10"/>
51
+ </div>
52
+ </div>
53
+ </li>
54
+ <!-- End of row-->
55
+
56
+ <li class='wide edq_wrapper' style='display: none;'>
57
+ <label for=<?php echo $prefix; ?>-edq-suggestions><?php echo $this->__('Suggestions'); ?></label>
58
+ <div class='input-box'>
59
+ <select id=<?php echo $prefix; ?>-edq-suggestions size='5' class='address-select' ></select>
60
+ </div>
61
+ </li>
62
+ <!-- End of row-->
63
+
64
+ <li class='fields edq_wrapper' style='display: none;'>
65
+ <div class='field edq_error_message'>
66
+ <label></label>
67
+ <div class='input-box' id=<?php echo $prefix; ?>-edq-error-message>
68
+ <input type='text' class='input-text' style='display: none;' disabled="disabled"/>
69
+ </div>
70
+ </div>
71
+ </li>
72
+ <!-- End of row-->
73
+
74
+ <li class='fields edq_wrapper' style='display: none;'>
75
+ <div class='field'>
76
+ <label></label>
77
+ <div class='input-box'>
78
+ <a href='javascript:void(0);' id=<?php echo $prefix; ?>-edq-unknown-postcode ><?php echo $this->__('If you don\'t know the postcode click here'); ?></a>
79
+ </div>
80
+ </div>
81
+ </li>
82
+ <!-- End of row-->
83
+
84
+ <li class='fields edq_wrapper' style='display: none;' >
85
+ <div class='field'>
86
+ <label></label>
87
+ <div class='input-box'>
88
+ <a href='javascript:void(0);' id=<?php echo $prefix; ?>-edq-known-postcode><?php echo $this->__('If you know the postcode click here'); ?></a>
89
+ </div>
90
+ </div>
91
+ </li>
92
+ <!-- End of row-->
93
+
94
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
95
+ <button id=<?php echo $prefix; ?>-edq-select-button title='<?php echo $this->__('Select'); ?>' type='button' class='button'>
96
+ <span>
97
+ <span><?php echo $this->__('Select'); ?></span>
98
+ </span>
99
+ </button>
100
+ <button id=<?php echo $prefix; ?>-edq-back-button-suggestions title='<?php echo $this->__('Back'); ?>' type='button' class='button'>
101
+ <span>
102
+ <span><?php echo $this->__('Back'); ?></span>
103
+ </span>
104
+ </button>
105
+ </div>
106
+ <!-- End of row -->
107
+
108
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
109
+ <button id=<?php echo $prefix; ?>-edq-change-address-button title='<?php echo $this->__('Change Address'); ?>' type='button' class='button'>
110
+ <span>
111
+ <span><?php echo $this->__('Change Address'); ?></span>
112
+ </span>
113
+ </button>
114
+ </div>
115
+ <!-- End of row -->
116
+
117
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
118
+ <button id=<?php echo $prefix; ?>-edq-try-again-button title='<?php echo $this->__('Try Again'); ?>' type='button' class='button'>
119
+ <span>
120
+ <span><?php echo $this->__('Try Again'); ?></span>
121
+ </span>
122
+ </button>
123
+ <button id=<?php echo $prefix; ?>-edq-back-button-tryagain title='<?php echo $this->__('Back'); ?>' type='button' class='button'>
124
+ <span>
125
+ <span><?php echo $this->__('Back'); ?></span>
126
+ </span>
127
+ </button>
128
+ </div>
129
+ <!-- End of row -->
130
+
131
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
132
+ <button id=<?php echo $prefix; ?>-edq-find-address-button title='<?php echo $this->__('Find Address'); ?>' type='button' class='button'>
133
+ <span>
134
+ <span><?php echo $this->__('Find Address'); ?></span>
135
+ </span>
136
+ </button>
137
+ </div>
138
+
139
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
140
+ <button id=<?php echo $prefix; ?>-edq-next-address-button title='<?php echo $this->__('Next'); ?>' type='button' class='button'>
141
+ <span>
142
+ <span><?php echo $this->__('Next'); ?></span>
143
+ </span>
144
+ </button>
145
+ <button id=<?php echo $prefix; ?>-edq-back-button-next title='<?php echo $this->__('Back'); ?>' type='button' class='button'>
146
+ <span>
147
+ <span><?php echo $this->__('Back'); ?></span>
148
+ </span>
149
+ </button>
150
+ </div>
151
+ <!-- End of row -->
152
+
153
+ <div class='buttons-set edq_wrapper form-buttons' style='display: none; margin-bottom: 10px;'>
154
+ <button id=<?php echo $prefix; ?>-edq-back-button title='<?php echo $this->__('Back'); ?>' type='button' class='button'>
155
+ <span>
156
+ <span><?php echo $this->__('Back'); ?></span>
157
+ </span>
158
+ </button>
159
+ </div>
160
+
161
+ <li style='display: none; clear:both;'>
162
+ &nbsp;
163
+ </li>
164
+ <!-- End of row-->
165
+
166
+ <li class='wide edq_wrapper form-buttons' style='display: none;'>
167
+ <label></label>
168
+ <div class='input-box' style="float: right;">
169
+ <a style="float: right;" href='javascript:void(0);' id=<?php echo $prefix; ?>-edq-manual-entry><?php echo $this->__('Enter address manually'); ?></a>
170
+ </div>
171
+ </li>
172
+ <!-- End of row-->
173
+
174
+ <li class='wide edq_wrapper form-buttons' style='display: none;'>
175
+ <label></label>
176
+ <div id=<?php echo $prefix; ?>-loader-please-wait style="float: right;" class='input-box'>
177
+ <span style="float: right; margin-left: 5px;"><?php echo $this->__('Loading next step...') ?></span>
178
+ <img style="display: inline; float: right;" src='<?php echo $this->getSkinUrl('ExperianDataQuality/images/opc-ajax-loader.gif', array('_area'=>'frontend')) ?>' alt='<?php echo $this->__('Loading next step...') ?>' title='<?php echo $this->__('Loading next step...') ?>' class='v-middle' />
179
+ </div>
180
+ </li>
181
+ <!-- End of row-->
182
+ </ul>
lib/EDQ/WshEmailValidator.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('WshValidator.php');
3
+
4
+ class WshEmailValidator extends WshValidator{
5
+ function __construct($email_service_url, $email_validation_key, $sleep_seconds_between_requests, $retries){
6
+ parent::__construct($email_service_url, $email_validation_key, $sleep_seconds_between_requests, $retries);
7
+ }
8
+
9
+ protected function _get_post_data($validation_request){
10
+ return json_encode(array('Email' => $validation_request[parent::EMAIL]));
11
+ }
12
+ }
lib/EDQ/WshPhoneValidator.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('WshValidator.php');
3
+
4
+ class WshPhoneValidator extends WshValidator{
5
+ function __construct($phone_service_url, $phone_validation_key, $sleep_seconds_between_requests, $retries){
6
+ parent::__construct($phone_service_url, $phone_validation_key, $sleep_seconds_between_requests, $retries);
7
+ }
8
+
9
+ protected function _get_post_data($validation_request){
10
+ return json_encode(array('DefaultCountryCode' => $validation_request[parent::AREA_CODE], 'Number' => $validation_request[parent::PHONE]));
11
+ }
12
+ }
lib/EDQ/WshValidator.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ abstract class WshValidator{
3
+ private $_validation_key;
4
+ private $_service_url;
5
+ private $_sleep_seconds_between_requests;
6
+ private $_retries;
7
+ private $_has_error;
8
+ private $_error_message;
9
+
10
+ const AREA_CODE = 'area_code';
11
+ const PHONE = 'phone';
12
+ const EMAIL = 'email';
13
+
14
+ function __construct($url, $_validation_key, $_sleep_seconds_between_requests, $_retries){
15
+ $this->_service_url = $url;
16
+ $this->_validation_key = $_validation_key;
17
+ $this->_sleep_seconds_between_requests = $_sleep_seconds_between_requests;
18
+ $this->_retries = $_retries;
19
+ $this->_has_error = false;
20
+ $this->_error_message = '';
21
+ }
22
+
23
+ public function has_error() {
24
+ return $this->_has_error;
25
+ }
26
+
27
+ public function get_error_message() {
28
+ return $this->_error_message;
29
+ }
30
+
31
+ public function validate($validation_request){
32
+ if (!is_array($validation_request)){
33
+ throw new Exception('The validation request must be a key value object.');
34
+ }
35
+
36
+ $data = $this->_get_post_data($validation_request);
37
+ return $this->_execute_validation($data);
38
+ }
39
+
40
+ abstract protected function _get_post_data($validation_request);
41
+
42
+ private function _execute_validation($data) {
43
+ $post_request = $this->_create_request($this->_service_url, 'post', $data);
44
+ $post_response = curl_exec($post_request);
45
+ $get_http_status = curl_getinfo($post_request, CURLINFO_HTTP_CODE);
46
+
47
+ curl_close($post_request);
48
+
49
+ if(!$this->_handle_http_status($get_http_status)) {
50
+ return;
51
+ }
52
+
53
+ list($post_response_headers, $post_content) = explode("\r\n\r\n", $post_response);
54
+
55
+ $get_request_url = '';
56
+ foreach (explode("\r\n", $post_response_headers) as $hdr) {
57
+ if (strpos($hdr, 'Content-Location: ') !== FALSE){
58
+ $get_request_url = substr($hdr, strlen('Content-Location: '));
59
+ break;
60
+ }
61
+ }
62
+
63
+ $get_request = $this->_create_request($get_request_url, 'get');
64
+
65
+ $get_response = '';
66
+ $http_status = '';
67
+ for ($i = 0; $i < $this->_retries; $i++){
68
+ sleep($this->_sleep_seconds_between_requests);
69
+ $get_response = curl_exec($get_request);
70
+ $http_status = curl_getinfo($get_request, CURLINFO_HTTP_CODE);
71
+ if ($http_status !== 409){
72
+ break;
73
+ }
74
+ }
75
+
76
+ if(!$this->_handle_http_status($http_status)) {
77
+ curl_close($get_request);
78
+ return;
79
+ }
80
+ list($get_response_headers, $get_content) = explode("\r\n\r\n", $get_response);
81
+
82
+ curl_close($get_request);
83
+
84
+ return $get_content;
85
+ }
86
+
87
+ private function _create_request($url, $method, $data = ''){
88
+ $request = curl_init($url);
89
+ curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method));
90
+ if (strcasecmp($method, 'post') === 0){
91
+ if ((!isset($data) || trim($data)==='')) {
92
+ throw new Exception('Expected post data.');
93
+ }
94
+
95
+ curl_setopt($request, CURLOPT_POSTFIELDS, $data);
96
+ }
97
+
98
+ curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
99
+ curl_setopt($request, CURLOPT_VERBOSE, 1);
100
+ curl_setopt($request, CURLOPT_HEADER, 1);
101
+ curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
102
+ curl_setopt($request, CURLOPT_HTTPHEADER, array(
103
+ 'Content-type: application/json',
104
+ 'Auth-Token: '.$this->_validation_key
105
+ ));
106
+
107
+ return $request;
108
+ }
109
+
110
+ private function _set_error_message($error_message) {
111
+ $this->_has_error = true;
112
+ $this->_error_message = $error_message;
113
+ }
114
+
115
+ private function _handle_http_status($http_status){
116
+ switch ($http_status){
117
+ case 200:
118
+ case 204:
119
+ return true;
120
+ case 409:
121
+ $this->_set_error_message('Service timeout.');
122
+ return false;
123
+ case 401:
124
+ $this->_set_error_message("Invalid validation key {$this->_validation_key}");
125
+ return false;
126
+ case 404:
127
+ $this->_set_error_message('The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.');
128
+ return false;
129
+ case 500:
130
+ $this->_set_error_message('Service exception.');
131
+ return false;
132
+ default:
133
+ throw new Exception("Unexpected HTTP status {$http_status}");
134
+ }
135
+ }
136
+ }
lib/EDQ/WshValidatorFactory.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('WshPhoneValidator.php');
3
+ require_once('WshEmailValidator.php');
4
+
5
+ class WshValidatorFactory{
6
+ const EMAIL = 'email';
7
+ const PHONE = 'phone';
8
+
9
+ public static function create($validator_type, $serice_url, $validation_key, $sleep_seconds_between_requests, $retries){
10
+ switch ($validator_type) {
11
+ case self::EMAIL:
12
+ return new WshEmailValidator($serice_url, $validation_key, $sleep_seconds_between_requests, $retries);
13
+ case self::PHONE:
14
+ return new WshPhoneValidator($serice_url, $validation_key, $sleep_seconds_between_requests, $retries);
15
+ default:
16
+ throw new Exception("Unsupported WSH validator: {$validator_type}.");
17
+ }
18
+ }
19
+ }
lib/ExperianDataQuality/Address.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'QAAddress.php';
3
+
4
+ class Address
5
+ {
6
+ public $QAAddress;
7
+ public $VerifyLevel;
8
+
9
+ public function __construct($response)
10
+ {
11
+ $this->QAAddress = isset($response->QAAddress) ? new QAAddress($response->QAAddress) : \FALSE;
12
+ $this->VerifyLevel = isset($response->VerifyLevel) ? $response->VerifyLevel : '';
13
+ }
14
+ }
lib/ExperianDataQuality/AddressLine.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'LineContentType.php';
3
+
4
+ class AddressLine
5
+ {
6
+ public $Label;
7
+ public $Line;
8
+ public $LineContent;
9
+ public $DataplusGroup;
10
+ public $Overflow = \FALSE;
11
+ public $Truncated = \FALSE;
12
+
13
+ public function __construct($response)
14
+ {
15
+ $this->Label = isset($response->Label) ? $response->Label : \FALSE;
16
+ $this->Line = isset($response->Line) ? $response->Line : \FALSE;
17
+ $this->LineContent = isset($response->LineContent) ? $response->LineContent : LineContentType::ADDRESS;
18
+ $this->DataplusGroup = isset($response->DataplusGroup) ? $response->DataplusGroup : \FALSE;
19
+ }
20
+ }
lib/ExperianDataQuality/AddressValidationParser.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php';
3
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Response/SearchResponse.php';
4
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Response/CanSearchResponse.php';
5
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Response/RefineResponse.php';
6
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Response/GetLayoutResponse.php';
7
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Response/GetAddressResponse.php';
8
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
9
+ include_once 'QALayouts.php';
10
+ include_once 'QASearchOk.php';
11
+ include_once 'QASearchResult.php';
12
+ include_once 'Picklist.php';
13
+ include_once 'Address.php';
14
+
15
+ /**
16
+ * ProOnDemand parser class.
17
+ */
18
+ class ExperianDataQuality_AddressValidationParser
19
+ {
20
+ public function parseDoGetLayouts(QALayouts $qaLayouts)
21
+ {
22
+ if(isset($qaLayouts) === \NULL)
23
+ {
24
+ throw new \Exception("qaLayouts");
25
+ }
26
+
27
+ $getAddressResponse = new GetLayoutResponse();
28
+ $getAddressResponse->Layouts = $qaLayouts->Layout;
29
+
30
+ return $getAddressResponse;
31
+ }
32
+
33
+ public function parseDoCanSearchResponse(QASearchOk $searchOK)
34
+ {
35
+ if(isset($searchOK) === \NULL)
36
+ {
37
+ throw new \Exception("searchOK");
38
+ }
39
+
40
+ $canSearchRequest = new CanSearchResponse();
41
+ $canSearchRequest->CanSearch = $searchOK->IsOk;
42
+ $canSearchRequest->ErrorMessage = $searchOK->ErrorMessage;
43
+ $canSearchRequest->ErrorCode = $searchOK->ErrorCode;
44
+ $canSearchRequest->ErrorDetail = $searchOK->ErrorDetail;
45
+
46
+ return $canSearchRequest;
47
+ }
48
+
49
+ public function parseDoSearchResponse(QASearchResult $searchResult)
50
+ {
51
+ if(isset($searchResult) === \NULL)
52
+ {
53
+ throw new \Exception("searchResult");
54
+ }
55
+
56
+ $searchResponse = new SearchResponse();
57
+ $searchResponse->PickListEntries = $searchResult->QAPicklist->PicklistEntry;
58
+ $searchResponse->Prompt = $searchResult->QAPicklist->Prompt;
59
+ $searchResponse->Total = $searchResult->QAPicklist->Total;
60
+ $searchResponse->MatchType = $searchResult->VerificationFlagsType;
61
+
62
+ return $searchResponse;
63
+ }
64
+
65
+ public function parseResponse($responseParameters, $value = \NULL)
66
+ {
67
+ $searchResponse = new SearchResponse();
68
+ $searchResponse->PickListEntries = $responseParameters->QAPicklist->PicklistEntry;
69
+ $searchResponse->Prompt = $responseParameters->QAPicklist->Prompt;
70
+ $searchResponse->Total = $responseParameters->QAPicklist->Total;
71
+ $searchResponse->MatchType = $responseParameters->VerificationFlagsType;
72
+
73
+ return $searchResponse;
74
+ }
75
+
76
+ public function parseDoRefineResponse(Picklist $doRefineResponse)
77
+ {
78
+ if(isset($doRefineResponse) === \NULL)
79
+ {
80
+ throw new \Exception("doRefineResponse");
81
+ }
82
+
83
+ $refineResponse = new RefineResponse();
84
+ $refineResponse->PickListEntries = $doRefineResponse->QAPicklist->PicklistEntry;
85
+ $refineResponse->Prompt = $doRefineResponse->QAPicklist->Prompt;
86
+ $refineResponse->Total = $doRefineResponse->QAPicklist->Total;
87
+ $refineResponse->MatchType = isset($doRefineResponse->VerificationFlagsType) ? $doRefineResponse->VerificationFlagsType : '';
88
+
89
+ return $refineResponse;
90
+ }
91
+
92
+ public function parseDoGetAddressResponse(Address $address, $dataSet)
93
+ {
94
+ if(isset($address) === \NULL)
95
+ {
96
+ throw new \Exception("address");
97
+ }
98
+
99
+ $getAddressResponse = new GetAddressResponse();
100
+ $getAddressResponse->MatchType = HelperMethods::isNullOrWhiteSpace($address->VerifyLevel) ? 'Verified': $address->VerifyLevel;
101
+ $getAddressResponse->DPVStatus = $address->QAAddress->DPVStatus;
102
+ $getAddressResponse->AddressLineDictionary = array();
103
+ $getAddressResponse->MissingSubPremise = $address->QAAddress->MissingSubPremise;
104
+ $getAddressResponse->Total = (int) 0;
105
+
106
+ $countOfAddressLines = count($address->QAAddress->AddressLine);
107
+ for ($index = 0; $index < $countOfAddressLines; $index++)
108
+ {
109
+ $getAddressResponse->AddressLineDictionary['Line' . $index] = $address->QAAddress->AddressLine[$index]->Line;
110
+
111
+ if($dataSet !== 'DE' && $dataSet !== 'US' && $dataSet !== 'CA') { continue; }
112
+
113
+ $label = trim($address->QAAddress->AddressLine[$index]->Label);
114
+ if(($label === "State" || $label === "State code" || $label === "Province code"))
115
+ {
116
+ $regionCode = $address->QAAddress->AddressLine[$index]->Line;
117
+ $region = $dataSet === 'DE'
118
+ ? Mage::getModel('directory/region')->loadByName($regionCode, $dataSet)
119
+ : Mage::getModel('directory/region')->loadByCode($regionCode, $dataSet);
120
+
121
+ $getAddressResponse->AddressLineDictionary['Line' . $index] = $region->getId();
122
+ }
123
+ }
124
+
125
+ return $getAddressResponse;
126
+ }
127
+ }
lib/ExperianDataQuality/AddressValidationReference.php ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QAAuthentication
3
+ {
4
+ private $Username;
5
+ private $Password;
6
+
7
+ public function __construct($username,$password)
8
+ {
9
+ $this->Username = $username;
10
+ $this->Password = $password;
11
+ }
12
+ }
13
+
14
+ class QAQueryHeader
15
+ {
16
+ private $QAAuthentication;
17
+ private $Security;
18
+
19
+ public function __construct($username,$password)
20
+ {
21
+ $this->QAAuthentication = new QAAuthentication($username, $password);
22
+ $this->Security = \NULL;
23
+ }
24
+ }
25
+
26
+ class QAGetLayouts
27
+ {
28
+ private $Country;
29
+
30
+ public function __construct($country)
31
+ {
32
+ $this->Country = $country;
33
+ }
34
+ }
35
+
36
+ class QALayouts
37
+ {
38
+ public $Layout = array();
39
+
40
+ public function __construct($response)
41
+ {
42
+ if(isset($response->Layout) === \FALSE)
43
+ {
44
+ $this->Layout = array();
45
+ }
46
+ else
47
+ {
48
+ if(is_array($response->Layout))
49
+ {
50
+ foreach ($response->Layout as $layout)
51
+ {
52
+ \array_push($this->Layout, new Layout($layout->Name, $layout->Comment));
53
+ }
54
+ }
55
+ else
56
+ {
57
+ \array_push($this->Layout, new Layout($layout->Name, $layout->Comment));
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ class Layout
64
+ {
65
+ public $Name;
66
+ public $Comment;
67
+
68
+ public function __construct($name, $comment)
69
+ {
70
+ $this->Name = $name;
71
+ $this->Comment = $comment;
72
+ }
73
+ }
74
+
75
+ class QACanSearch
76
+ {
77
+ private $Country;
78
+ private $Engine;
79
+ private $Layout;
80
+ private $Localisation;
81
+
82
+ public function __construct($countryField, $engineField, $layoutField, $localisationField = \NULL)
83
+ {
84
+ $this->Country = $countryField;
85
+ $this->Engine = $engineField;
86
+ $this->Layout = $layoutField;
87
+ $this->Localisation = $localisationField;
88
+ }
89
+ }
90
+
91
+ class QASearchOk
92
+ {
93
+ public $IsOk;
94
+ public $ErrorCode;
95
+ public $ErrorMessage;
96
+ public $ErrorDetail;
97
+
98
+ public function __construct($response)
99
+ {
100
+ $this->IsOk = isset($response->IsOk) ? $response->IsOk : \FALSE;
101
+ $this->ErrorCode = isset($response->ErrorCode) ? $response->ErrorCode : \FALSE;
102
+ $this->ErrorMessage = isset($response->ErrorMessage) ? $response->ErrorMessage : \FALSE;
103
+ $this->ErrorDetail = isset($response->ErrorDetail) ? $response->ErrorDetail : \FALSE;
104
+ }
105
+ }
106
+
107
+ class QASearch
108
+ {
109
+ private $Country;
110
+ private $Engine;
111
+ private $Layout;
112
+ private $Search;
113
+ private $FormattedAddressInPicklist;
114
+ private $Localisation;
115
+
116
+ public function __construct($countryField, $engineField, $layoutField, $searchField, $localisationField = \NULL)
117
+ {
118
+ $this->Country = $countryField;
119
+ $this->Engine = $engineField;
120
+ $this->Layout = $layoutField;
121
+ $this->Search = $searchField;
122
+
123
+ if(isset($localisationField))
124
+ {
125
+ $this->Localisation = $localisationField;
126
+ }
127
+
128
+ $this->FormattedAddressInPicklist = \FALSE;
129
+ }
130
+ }
131
+
132
+ class QASearchResult
133
+ {
134
+ public $QAPicklist;
135
+ public $QAAddress;
136
+ public $VerificationFlags;
137
+ public $VerificationFlagsType;
138
+
139
+ public function __construct($response)
140
+ {
141
+ $this->QAPicklist = isset($response->QAPicklist) ? new QAPicklist($response->QAPicklist) : FALSE;
142
+ $this->QAAddress = isset($response->QAAddress) ? $response->QAAddress : FALSE;
143
+ $this->VerificationFlags = isset($response->VerificationFlags) ? $response->VerificationFlags : FALSE;
144
+ $this->VerificationFlagsType = isset($response->VerifyLevel) ? $response->VerifyLevel : VerifyLevelType::NONE;
145
+ }
146
+ }
147
+
148
+ class QAPicklist
149
+ {
150
+ public $FullPicklistMoniker;
151
+ public $PicklistEntry = array();
152
+ public $Prompt;
153
+ public $Total;
154
+ public $AutoFormatSafe = \FALSE;
155
+ public $AutoFormatPastClose = \FALSE;
156
+ public $AutoStepinSafe = \FALSE;
157
+ public $AutoStepinPastClose = \FALSE;
158
+ public $LargePotential = \FALSE;
159
+ public $MaxMatches = \FALSE;
160
+ public $MoreOtherMatches = \FALSE;
161
+ public $OverThreshold = \FALSE;
162
+ public $Timeout = \FALSE;
163
+
164
+ public function __construct($response)
165
+ {
166
+ if(isset($response->PicklistEntry) === \FALSE)
167
+ {
168
+ $this->PicklistEntry = array();
169
+ }
170
+ else
171
+ {
172
+ if(is_array($response->PicklistEntry))
173
+ {
174
+ foreach ($response->PicklistEntry as $value)
175
+ {
176
+ \array_push($this->PicklistEntry, new PicklistEntry($value));
177
+ }
178
+ }
179
+ else
180
+ {
181
+ \array_push($this->PicklistEntry, new PicklistEntry($response->PicklistEntry));
182
+ }
183
+ }
184
+ $this->FullPicklistMoniker = isset($response->FullPicklistMoniker) ? $response->FullPicklistMoniker : \FALSE;
185
+ $this->Prompt = isset($response->Prompt) ? $response->Prompt : \FALSE;
186
+ $this->Total = isset($response->Total) ? $response->Total : \FALSE;
187
+ }
188
+ }
189
+
190
+ class PicklistEntry
191
+ {
192
+ public $Moniker;
193
+ public $PartialAddress;
194
+ public $PickList;
195
+ public $Postcode;
196
+ public $Score;
197
+ public $FullAddress;
198
+ public $Multiples;
199
+ public $CanStep = \FALSE;
200
+ public $AliasMatch = \FALSE;
201
+ public $PostcodeRecoded = \FALSE;
202
+ public $CrossBorderMatch = \FALSE;
203
+ public $DummyPOBox = \FALSE;
204
+ public $Name = \FALSE;
205
+ public $Information = \FALSE;
206
+ public $WarnInformation = \FALSE;
207
+ public $IncompleteAddr = \FALSE;
208
+ public $UnresolvableRange;
209
+ public $PhantomPrimaryPoint = \FALSE;
210
+ public $SubsidiaryData = \FALSE;
211
+ public $ExtendedData = \FALSE;
212
+ public $EnhancedData = \FALSE;
213
+
214
+ public function __construct($response)
215
+ {
216
+ $this->Moniker = isset($response->Moniker) ? $response->Moniker : \FALSE;
217
+ $this->PartialAddress = isset($response->PartialAddress) ? $response->PartialAddress : \FALSE;
218
+ $this->PickList = isset($response->Picklist) ? $response->Picklist : \FALSE;
219
+ $this->Postcode = isset($response->Postcode) ? $response->Postcode : \FALSE;
220
+ $this->Score = isset($response->Score) ? $response->Score : \FALSE;
221
+ $this->FullAddress = isset($response->FullAddress) ? $response->FullAddress : \FALSE;
222
+ $this->UnresolvableRange = isset($response->UnresolvableRange) ? $response->UnresolvableRange : \FALSE;
223
+ }
224
+ }
225
+
226
+ class QARefine
227
+ {
228
+ private $Moniker;
229
+ private $Refinement;
230
+ private $Layout;
231
+ private $Threshold;
232
+ private $Timeout;
233
+ private $Localisation = \FALSE;
234
+ private $FormattedAddressInPicklist = \FALSE;
235
+
236
+ public function __construct($monikerField, $refinementField, $layoutField, $thresholdField, $timeoutField)
237
+ {
238
+ $this->Moniker = $monikerField;
239
+ $this->Refinement = $refinementField;
240
+ $this->Layout = $layoutField;
241
+ $this->Threshold = $thresholdField;
242
+ $this->Timeout = $timeoutField;
243
+ }
244
+ }
245
+
246
+ class Picklist
247
+ {
248
+ public $QAPicklist;
249
+
250
+ public function __construct($response)
251
+ {
252
+ $this->QAPicklist = isset($response->QAPicklist) ? new QAPicklist($response->QAPicklist) : \FALSE;
253
+ }
254
+ }
255
+
256
+ class QAGetAddress
257
+ {
258
+ private $Layout;
259
+ private $Moniker;
260
+ private $Localisation = \FALSE;
261
+
262
+ public function __construct($layoutField, $monikerField)
263
+ {
264
+ $this->Layout = $layoutField;
265
+ $this->Moniker = $monikerField;
266
+ }
267
+ }
268
+
269
+ class Address
270
+ {
271
+ public $QAAddress;
272
+ public $VerifyLevel;
273
+
274
+ public function __construct($response)
275
+ {
276
+ $this->QAAddress = isset($response->QAAddress) ? new QAAddress($response->QAAddress) : \FALSE;
277
+ $this->VerifyLevel = isset($response->VerifyLevel) ? $response->VerifyLevel : '';
278
+ }
279
+ }
280
+
281
+ class QAAddress
282
+ {
283
+ public $AddressLine = array();
284
+ public $Overflow;
285
+ public $Truncated;
286
+ public $DPVStatus;
287
+ public $DPVStatusSpecified;
288
+ public $MissingSubPremise;
289
+
290
+ public function __construct($response)
291
+ {
292
+ if(isset($response->AddressLine) === \FALSE)
293
+ {
294
+ $this->AddressLine = array();
295
+ }
296
+ else
297
+ {
298
+ if(is_array($response->AddressLine))
299
+ {
300
+ foreach ($response->AddressLine as $value)
301
+ {
302
+ \array_push($this->AddressLine, new AddressLine($value));
303
+ }
304
+ }
305
+ else
306
+ {
307
+ \array_push($this->AddressLine, new AddressLine($response->AddressLine));
308
+ }
309
+ }
310
+
311
+ $this->Overflow = \FALSE;
312
+ $this->Truncated = \FALSE;
313
+ $this->DPVStatus = isset($response->DPVStatus) ? $response->DPVStatus : \FALSE;
314
+ $this->DPVStatusSpecified = isset($response->DPVStatusSpecified) ? $response->DPVStatusSpecified : DPVStatusType::DPVNOTCONFIRMED;
315
+ $this->MissingSubPremise = isset($response->MissingSubPremise) ? $response->MissingSubPremise : \FALSE;
316
+ }
317
+ }
318
+
319
+ class AddressLine
320
+ {
321
+ public $Label;
322
+ public $Line;
323
+ public $LineContent;
324
+ public $DataplusGroup;
325
+ public $Overflow = \FALSE;
326
+ public $Truncated = \FALSE;
327
+
328
+ public function __construct($response)
329
+ {
330
+ $this->Label = isset($response->Label) ? $response->Label : \FALSE;
331
+ $this->Line = isset($response->Line) ? $response->Line : \FALSE;
332
+ $this->LineContent = isset($response->LineContent) ? $response->LineContent : LineContentType::ADDRESS;
333
+ $this->DataplusGroup = isset($response->DataplusGroup) ? $response->DataplusGroup : \FALSE;
334
+ }
335
+ }
336
+
337
+ class DPVStatusType
338
+ {
339
+ const DPVNOTCONFIGURED = 'DPVNotConfigured';
340
+ const DPVCONFIGURED = 'DPVConfigured';
341
+ const DPVCONFIRMED = 'DPVConfirmed';
342
+ const DPVCONFIRMEDMISSINGSEC = 'DPVConfirmedMissingSec';
343
+ const DPVNOTCONFIRMED = 'DPVNotConfirmed';
344
+ const DPVLOCKED = 'DPVLocked';
345
+ const DPVSEEDHIT = 'DPVSeedHit';
346
+ }
347
+
348
+ class EngineType
349
+ {
350
+ public $EngineType = array();
351
+ public $PromptSet;
352
+ private $Flatten;
353
+ private $FlattenSpecified;
354
+ private $Intensity;
355
+ private $IntensitySpecified;
356
+ private $PromptSetSpecified;
357
+ private $Threshold;
358
+ private $Timeout;
359
+ private $Value;
360
+
361
+ public function __construct($flattenField, $promptSetFieldSpecified, $thresholdField, $timeoutField, $valueField, $flattenSpecified = \NULL, $intensity = \NULL, $intensitySpecified= \NULL)
362
+ {
363
+ $this->Value = $valueField;
364
+ $this->Flatten = $flattenField;
365
+ $this->PromptSetSpecified = $promptSetFieldSpecified;
366
+ $this->Threshold = $thresholdField;
367
+ $this->Timeout = $timeoutField;
368
+
369
+ if(isset($flattenSpecified))
370
+ {
371
+ $this->FlattenSpecified = $flattenSpecified;
372
+ }
373
+
374
+ if(isset($intensity))
375
+ {
376
+ $this->Intensity = $intensity;
377
+ }
378
+
379
+ if(isset($intensitySpecified))
380
+ {
381
+ $this->IntensitySpecified = $intensitySpecified;
382
+ }
383
+
384
+ $this->EngineType = array(
385
+ '_' => $this->Value,
386
+ 'Flatten' => $this->Flatten,
387
+ 'PromptSet' => $this->PromptSet
388
+ );
389
+ }
390
+ }
391
+
392
+ class EngineEnumType
393
+ {
394
+ const SINGLELINE = 'Singleline';
395
+ const TYPEDOWN = 'Typedown';
396
+ const VERIFICATION = 'Verification';
397
+ const KEYFINDER = 'Keyfinder';
398
+ const INTUITIVE = 'Intuitive';
399
+ }
400
+
401
+ class PromptSetType
402
+ {
403
+ //const \DEFAULT = 'Default';
404
+ const ONELINE = 'OneLine';
405
+ const GENERIC = 'Generic';
406
+ const OPTIMAL = 'Optimal';
407
+ const ALTERNATE = 'Alternate';
408
+ const ALTERNATE2 = 'Alternate2';
409
+ const ALTERNATE3 = 'Alternate3';
410
+ }
411
+
412
+ class VerifyLevelType
413
+ {
414
+ const NONE = 'None';
415
+ const VERIFIED = 'Verified';
416
+ const INTERACTIONREQUIRED = 'InteractionRequired';
417
+ const PREMISSESPARTIAL = 'PremisesPartial';
418
+ const STREETPARTIAL = 'StreetPartial';
419
+ const MULTIPLE = 'Multiple';
420
+ const VERIFIEDPLACE = 'VerifiedPlace';
421
+ const VERIFIEDSTREET = 'VerifiedStreet';
422
+ }
423
+
424
+ class LineContentType
425
+ {
426
+ const NONE = 'None';
427
+ const ADDRESS= 'Address';
428
+ const NAME = 'Name';
429
+ const ANCILLARY= 'Ancillary';
430
+ const DATAPLUS = 'DataPlus';
431
+ }
432
+ ?>
lib/ExperianDataQuality/BaseService.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetLayoutsRequest.php';
3
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/CanSearchRequest.php';
4
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php';
5
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/RefineRequest.php';
6
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetAddressRequest.php';
7
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/GlobalSettings.php';
8
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
9
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/BaseSearchRequest.php';
10
+ include_once 'AddressValidationParser.php';
11
+ include_once 'QAGetLayouts.php';
12
+ include_once 'QALayouts.php';
13
+ include_once 'QACanSearch.php';
14
+ include_once 'QASearchOk.php';
15
+ include_once 'QASearch.php';
16
+ include_once 'QASearchResult.php';
17
+ include_once 'QARefine.php';
18
+ include_once 'Picklist.php';
19
+ include_once 'QAGetAddress.php';
20
+ include_once 'Address.php';
21
+ include_once 'EngineType.php';
22
+ include_once 'EngineEnumType.php';
23
+
24
+ abstract class ExperianDataQuality_BaseService
25
+ {
26
+ private static $parser = \NULL;
27
+ protected $client = \NULL;
28
+
29
+ public function __construct()
30
+ {
31
+ self::$parser = new ExperianDataQuality_AddressValidationParser();
32
+ }
33
+
34
+ public function doGetLayouts(GetLayoutsRequest $doGetLayoutsRequest)
35
+ {
36
+ $this->_checkForErrors($doGetLayoutsRequest);
37
+ $this->_setLocation();
38
+
39
+ $getLayoutsRequest = new QAGetLayouts($doGetLayoutsRequest->Country);
40
+ $qALayoutsResponse = new QALayouts($this->client->doGetLayouts($getLayoutsRequest));
41
+
42
+ return self::$parser->parseDoGetLayouts($qALayoutsResponse);
43
+ }
44
+
45
+ public function doCanSearch(CanSearchRequest $canSearchRequest)
46
+ {
47
+ $this->_checkForErrors($canSearchRequest);
48
+
49
+ $layout = $this->_getLayout($canSearchRequest->DataSet, $canSearchRequest->Layout);
50
+ $engine = $this->_getEngineType($canSearchRequest->DataSet, $canSearchRequest->promptSetType());
51
+
52
+ $this->_setLocation($canSearchRequest->Location);
53
+
54
+ $qACanSearch = new QACanSearch($canSearchRequest->DataSet, $engine, $layout);
55
+ $qASearchOkResponse = new QASearchOk($this->client->doCanSearch($qACanSearch));
56
+
57
+ return self::$parser->parseDoCanSearchResponse($qASearchOkResponse);
58
+ }
59
+
60
+ public function doSearch(BaseSearchRequest $baseRequest, $searchAddress = "")
61
+ {
62
+ $this->_checkForErrors($baseRequest);
63
+
64
+ $layout = $this->_getLayout($baseRequest->DataSet, $baseRequest->Layout);
65
+ $engine = $this->_getEngineType($baseRequest->DataSet, $baseRequest->promptSetType());
66
+
67
+ $this->_setLocation();
68
+
69
+ $iso3 = Mage::getModel('directory/country')->load($baseRequest->DataSet)->getIso3Code();
70
+ if($iso3 === 'USA' && GlobalSettings::instance()->getIsATIEnabled())
71
+ {
72
+ $iso3 = 'USE';
73
+ }
74
+
75
+ $qASearchRequest = new QASearch($iso3, $engine, $layout, $searchAddress);
76
+ $doSearchResponse = $this->client->doSearch($qASearchRequest);
77
+
78
+ if($engine['_'] === EngineEnumType::VERIFICATION && ($doSearchResponse->VerifyLevel === 'Verified' || $doSearchResponse->VerifyLevel === 'InteractionRequired'))
79
+ {
80
+ $address = new Address($doSearchResponse);
81
+ return self::$parser->parseDoGetAddressResponse($address, $baseRequest->DataSet);
82
+ }
83
+ else
84
+ {
85
+ $qASearchResult = new QASearchResult($doSearchResponse);
86
+ return self::$parser->parseResponse($qASearchResult);
87
+ }
88
+ }
89
+
90
+ public function doRefine(RefineRequest $refineRequest)
91
+ {
92
+ $this->_checkForErrors($refineRequest);
93
+
94
+ $layout = $this->_getLayout($refineRequest->DataSet, $refineRequest->Layout);
95
+ $threshold = GlobalSettings::instance()->proOnDemandThreshold();
96
+ $timeout = GlobalSettings::instance()->proOnDemandTimeout();
97
+
98
+ $this->_setLocation();
99
+
100
+ $doRefineRequest = new QARefine($refineRequest->Moniker, $refineRequest->Refinement, $layout, $threshold, $timeout);
101
+ $PicklistResponse = new Picklist($this->client->doRefine($doRefineRequest));
102
+
103
+ return self::$parser->ParseDoRefineResponse($PicklistResponse);
104
+ }
105
+
106
+ public function doGetAddress(GetAddressRequest $getAddressRequest)
107
+ {
108
+ $this->_checkForErrors($getAddressRequest);
109
+
110
+ $layout = $this->_getLayout($getAddressRequest->DataSet, $getAddressRequest->Layout);
111
+
112
+ $this->_setLocation();
113
+
114
+ $addressRequest = new QAGetAddress($layout, $getAddressRequest->Moniker);
115
+ $getAddressResponse = new Address($this->client->doGetAddress($addressRequest));
116
+
117
+ return self::$parser->parseDoGetAddressResponse($getAddressResponse, $getAddressRequest->DataSet);
118
+ }
119
+
120
+ private static function _getLayout($dataSet, $layout)
121
+ {
122
+ if(HelperMethods::isNullOrWhiteSpace($layout) === \FALSE)
123
+ {
124
+ return $layout;
125
+ }
126
+
127
+ return GlobalSettings::instance()->defaultLayout($dataSet);
128
+ }
129
+
130
+ //EngineType
131
+ private static function _getEngineType($dataSet, $promptSetType = \NULL)
132
+ {
133
+ $flatten = GlobalSettings::instance()->defaultFlatten();
134
+ $promptSetSpecified = GlobalSettings::instance()->defaultPromptSetSpecified();
135
+ $threshold = GlobalSettings::instance()->proOnDemandThreshold();
136
+ $timeout = GlobalSettings::instance()->proOnDemandTimeout();
137
+ $value = GlobalSettings::instance()->defaultEngineEnumType($dataSet);
138
+
139
+ $engineType = new EngineType($flatten, $promptSetSpecified, $threshold, $timeout, $value);
140
+
141
+ if(isset($promptSetType))
142
+ {
143
+ $engineType->EngineType['PromptSet'] = $promptSetType;
144
+ }
145
+
146
+ return $engineType->EngineType;
147
+ }
148
+
149
+ private function _checkForErrors($request)
150
+ {
151
+ if(!isset($request))
152
+ {
153
+ throw new \Exception("The $request cannot be null.");
154
+ }
155
+
156
+ $errors = array();
157
+ if($request->isValid($errors) === \FALSE)
158
+ {
159
+ $message = \implode(" ", $errors);
160
+ throw new \Exception($message);
161
+ }
162
+ }
163
+
164
+ protected abstract function _setLocation($location = NULL);
165
+ }
lib/ExperianDataQuality/Common/GlobalSettings.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Application settings.
4
+ */
5
+ class GlobalSettings
6
+ {
7
+ private $settingsProvider;
8
+
9
+ function __construct(Mage_Core_Helper_Abstract $settingsProvider)
10
+ {
11
+ $this->settingsProvider = $settingsProvider;
12
+ }
13
+
14
+ public static function instance()
15
+ {
16
+ static $instance = \NULL;
17
+ if($instance === \NULL)
18
+ {
19
+ $instance = new GlobalSettings(Mage::helper('addressvalidation/Settings'));
20
+ }
21
+
22
+ return $instance;
23
+ }
24
+
25
+ public function getServiceProvide()
26
+ {
27
+ return $this->settingsProvider->getServiceType();
28
+ }
29
+
30
+ public function getOnDemandToken()
31
+ {
32
+ return $this->settingsProvider->getOnDemandToken();
33
+ }
34
+
35
+ public function getOnDemandEndpoint()
36
+ {
37
+ return $this->settingsProvider->getOnDemandEndpoint();
38
+ }
39
+ public function proOnDemandThreshold()
40
+ {
41
+ return '25';
42
+ }
43
+
44
+ public function proOnDemandTimeout()
45
+ {
46
+ return '1000';
47
+ }
48
+
49
+ public function proOnDemandRequestTag()
50
+ {
51
+ return '';
52
+ }
53
+
54
+ public function defaultLayout($dataSet)
55
+ {
56
+ switch ($dataSet)
57
+ {
58
+ case 'US':
59
+ case 'USA':
60
+ if($this->getIsATIEnabled())
61
+ {
62
+ return $this->settingsProvider->getUSELayout();
63
+ }
64
+ return $this->settingsProvider->getUSALayout();
65
+ case 'CA':
66
+ case 'CAN':
67
+ return $this->settingsProvider->getCANLayout();
68
+ case 'GB':
69
+ case 'GBR':
70
+ return $this->settingsProvider->getGBRLayout();
71
+ case 'DE':
72
+ case 'DEU':
73
+ return $this->settingsProvider->getDEULayout();
74
+ case 'IE':
75
+ case 'IRL':
76
+ return $this->settingsProvider->getIRLLayout();
77
+ default:
78
+ return '';
79
+ }
80
+ }
81
+
82
+ public function defaultEngineEnumType($dataSet)
83
+ {
84
+ switch ($dataSet)
85
+ {
86
+ case 'US':
87
+ case 'USA':
88
+ case 'USE':
89
+ case 'CA':
90
+ case 'CAN':
91
+ return EngineEnumType::VERIFICATION;
92
+ case 'GB':
93
+ case 'GBR':
94
+ case 'DE':
95
+ case 'DEU':
96
+ case 'IE':
97
+ case 'IRL':
98
+ return EngineEnumType::SINGLELINE;
99
+ default:
100
+ return '';
101
+ }
102
+ }
103
+
104
+ public function defaultPromptSetType()
105
+ {
106
+ return 'Default';
107
+ }
108
+
109
+ public function defaultFlatten()
110
+ {
111
+ return \TRUE;
112
+ }
113
+
114
+ public function defaultPromptSetSpecified()
115
+ {
116
+ return \TRUE;
117
+ }
118
+
119
+ public function getIsATIEnabled()
120
+ {
121
+ return $this->settingsProvider->isATIEnabled();
122
+ }
123
+
124
+ public function getIsUsingProxy()
125
+ {
126
+ return $this->settingsProvider->isUsingProxy();
127
+ }
128
+
129
+ public function getProxyName()
130
+ {
131
+ return $this->settingsProvider->getProxyName();
132
+ }
133
+
134
+ public function getProxyPort()
135
+ {
136
+ return $this->settingsProvider->getProxyPort();
137
+ }
138
+
139
+ public function getProxyUser()
140
+ {
141
+ return $this->settingsProvider->getProxyUser();
142
+ }
143
+
144
+ public function getProxyPassword()
145
+ {
146
+ return $this->settingsProvider->getProxyPassword();
147
+ }
148
+ }
lib/ExperianDataQuality/Common/HelperMethods.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HelperMethods
3
+ {
4
+ /**
5
+ * Indicates whether a specified string is null, empty, or consists
6
+ * only of white-space characters.
7
+ *
8
+ * @param string $value The string to test
9
+ * @return true if the value parameter is null,
10
+ * or if value consists exclusively of white-space characters.
11
+ */
12
+ public static function isNullOrWhiteSpace($value)
13
+ {
14
+ $isValid = \FALSE;
15
+
16
+ if ((!isset($value) || trim($value) === ''))
17
+ {
18
+ $isValid = \TRUE;
19
+ }
20
+
21
+ return $isValid;
22
+ }
23
+
24
+ public static function startsWith($needle, $haystack)
25
+ {
26
+ $beginingToCompare = substr($haystack, 0, strlen($needle));
27
+ return (strcmp($beginingToCompare, $needle) == 0);
28
+ }
29
+ }
lib/ExperianDataQuality/Common/Request/BaseAddressRequest.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
3
+ /**
4
+ * Holds the base address request data for ProOnDemand WS.
5
+ */
6
+ class BaseAddressRequest
7
+ {
8
+ /* @var $Moniker String */
9
+ public $Moniker;
10
+
11
+ /* @var $DataSet String */
12
+ public $DataSet;
13
+
14
+ /* @var $Layout String */
15
+ public $Layout;
16
+
17
+ /**
18
+ * Validates the request information
19
+ *
20
+ * @param string $errors Request errors.
21
+ * @return True of False whether the data is valid.
22
+ */
23
+ public function isValid(&$errors)
24
+ {
25
+ if (!isset($errors))
26
+ {
27
+ $errors = array();
28
+ }
29
+
30
+ if(HelperMethods::isNullOrWhiteSpace($this->DataSet))
31
+ {
32
+ \array_push($errors, 'The dateset is not specified.');
33
+ }
34
+
35
+ if(HelperMethods::isNullOrWhiteSpace($this->Moniker))
36
+ {
37
+ \array_push($errors, 'The moniker is not specified.');
38
+ }
39
+
40
+ return \count($errors) === 0;
41
+ }
42
+ }
lib/ExperianDataQuality/Common/Request/BaseSearchRequest.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
3
+ /**
4
+ * Base search request data for ProOnDemand WS.
5
+ */
6
+ abstract class BaseSearchRequest
7
+ {
8
+ /* @var $DataSet String */
9
+ public $DataSet;
10
+
11
+ /* @var $PromptSet String */
12
+ public $PromptSet;
13
+
14
+ /* @var $Engine String */
15
+ public $Engine;
16
+
17
+ /* @var $Layout String */
18
+ public $Layout;
19
+
20
+ /* @var $DataCenter String */
21
+ public $DataCenter;
22
+
23
+ /* @var $Service String */
24
+ public $Service;
25
+
26
+ /**
27
+ * Validates the request information
28
+ *
29
+ * @param string $errors Request errors.
30
+ * @return True of False whether the data is valid.
31
+ */
32
+ public function isValid(&$errors)
33
+ {
34
+ if (!isset($errors))
35
+ {
36
+ $errors = array();
37
+ }
38
+
39
+ if(HelperMethods::isNullOrWhiteSpace($this->DataSet))
40
+ {
41
+ \array_push($errors, 'The DataSet is not specified');
42
+ }
43
+
44
+ return \count($errors) === 0;
45
+ }
46
+
47
+ public function promptSetType()
48
+ {
49
+ return 'Default';
50
+ }
51
+
52
+ public function engineEnumType()
53
+ {
54
+ /*
55
+ if(HelperMethods::isNullOrWhiteSpace($this->Engine) !== \TRUE)
56
+ {
57
+ if(EngineEnumType::isValidValue($this->Engine) === \FALSE)
58
+ {
59
+ $message = "Engine enum type " . $this->Engine . " is not supported.";
60
+ throw new \Exception($message);
61
+ }
62
+
63
+ return $this->Engine;
64
+ }
65
+
66
+ return GlobalSettings::instance()->defaultEngineEnumType($this->DataSet);
67
+ * */
68
+ }
69
+ }
lib/ExperianDataQuality/Common/Request/CanSearchRequest.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once "BaseSearchRequest.php";
3
+
4
+ /**
5
+ * Can search request data for ProOnDemand WS.
6
+ */
7
+ class CanSearchRequest extends BaseSearchRequest
8
+ {
9
+ public $Location;
10
+ }
lib/ExperianDataQuality/Common/Request/GetAddressRequest.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once "BaseAddressRequest.php";
3
+
4
+ /**
5
+ * Address request data for ProOnDemand WS.
6
+ */
7
+ class GetAddressRequest extends BaseAddressRequest { }
lib/ExperianDataQuality/Common/Request/GetLayoutsRequest.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseSearchRequest.php';
3
+
4
+ class GetLayoutsRequest extends BaseSearchRequest
5
+ {
6
+ /* @var $Layout String */
7
+ public $Country;
8
+
9
+ public $qaQueryHeader = null;
10
+
11
+ /**
12
+ * Validates the request information
13
+ *
14
+ * @param string $errors Request errors.
15
+ * @return True of False whether the data is valid.
16
+ */
17
+ public function isValid(&$errors)
18
+ {
19
+ if (!isset($errors))
20
+ {
21
+ $errors = array();
22
+ }
23
+
24
+ if(HelperMethods::isNullOrWhiteSpace($this->Country))
25
+ {
26
+ \array_push($errors, 'The country is not specified.');
27
+ }
28
+
29
+ return \count($errors) === 0;
30
+ }
31
+ }
lib/ExperianDataQuality/Common/Request/RefineRequest.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseAddressRequest.php';
3
+ /**
4
+ * Refine request data for ProOnDemand WS.
5
+ */
6
+ class RefineRequest extends BaseAddressRequest
7
+ {
8
+ public $Refinement;
9
+ }
lib/ExperianDataQuality/Common/Request/SearchRequest.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseSearchRequest.php';
3
+ /*
4
+ * Search request data for ProOnDemand WS.and open the template in the editor.
5
+ */
6
+ class SearchRequest extends BaseSearchRequest {
7
+ /* @var $Street1 String */
8
+ public $Street1;
9
+
10
+ /* @var $Street2 String */
11
+ public $Street2;
12
+
13
+ /* @var $BuildingNumberOrName String */
14
+ public $BuildingNumberOrName;
15
+
16
+ /* @var $City String */
17
+ public $City;
18
+
19
+ /* @var $State String */
20
+ public $State;
21
+
22
+ /* @var $Postcode String */
23
+ public $Postcode;
24
+
25
+ /* @var $TownOrLacality String */
26
+ public $TownOrLacality;
27
+
28
+ /**
29
+ * Validates the request information
30
+ *
31
+ * @param string $errors Request errors.
32
+ * @return True of False whether the data is valid.
33
+ */
34
+ public function isValid(&$errors)
35
+ {
36
+ if (!isset($errors))
37
+ {
38
+ $errors = array();
39
+ }
40
+
41
+ if (HelperMethods::isNullOrWhiteSpace($this->Street1)
42
+ && HelperMethods::isNullOrWhiteSpace($this->Street2)
43
+ && HelperMethods::isNullOrWhiteSpace($this->BuildingNumberOrName)
44
+ && HelperMethods::isNullOrWhiteSpace($this->City)
45
+ && HelperMethods::isNullOrWhiteSpace($this->State)
46
+ && HelperMethods::isNullOrWhiteSpace($this->Postcode)
47
+ && HelperMethods::isNullOrWhiteSpace($this->TownOrLacality))
48
+ {
49
+ \array_push($errors, 'Please enter exact details.');
50
+
51
+ return \FALSE;
52
+ }
53
+
54
+ return \count($errors) === 0;
55
+ }
56
+ }
lib/ExperianDataQuality/Common/Response/BaseSearchResponse.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Holds the base search response data from ProOnDemand WS.
4
+ */
5
+ class BaseSearchResponse
6
+ {
7
+ /* @var $PickListEntries IEnumerable<PickListEntry> */
8
+ public $PickListEntries = array();
9
+
10
+ /* @var $Prompt String */
11
+ public $Prompt;
12
+
13
+ /* @var $Total String */
14
+ public $Total;
15
+
16
+ /* @var $ErrorMessage String */
17
+ public $ErrorMessage;
18
+
19
+ /* @var $MatchType String */
20
+ public $MatchType;
21
+
22
+ /* @var $MatchType String */
23
+ public $DPVStatus;
24
+ }
lib/ExperianDataQuality/Common/Response/CanSearchResponse.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseSearchResponse.php';
3
+
4
+ /**
5
+ * Holds the can search response data from ProOnDemand WS.
6
+ */
7
+ class CanSearchResponse extends BaseSearchResponse
8
+ {
9
+ /* @var $CanSearch Boolean */
10
+ public $CanSearch;
11
+
12
+ /* @var $ErrorCode String */
13
+ public $ErrorCode;
14
+
15
+ /* @var $ErrorDetail String */
16
+ public $ErrorDetail;
17
+ }
lib/ExperianDataQuality/Common/Response/GetAddressResponse.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseSearchResponse.php';
3
+
4
+ /**
5
+ * Holds the address response data from ProOnDemand WS.
6
+ */
7
+ class GetAddressResponse extends BaseSearchResponse
8
+ {
9
+ /* @var $AddressLineDictionary Dictinary */
10
+ public $AddressLineDictionary = array();
11
+
12
+ public $MissingSubPremise;
13
+ }
lib/ExperianDataQuality/Common/Response/GetLayoutResponse.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'BaseSearchResponse.php';
3
+
4
+ class GetLayoutResponse extends BaseSearchResponse
5
+ {
6
+ public $Layouts = array();
7
+ }
lib/ExperianDataQuality/Common/Response/RefineResponse.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once "BaseSearchResponse.php";
3
+
4
+ /**
5
+ * Holds the refine response data from ProOnDemand WS.
6
+ */
7
+ class RefineResponse extends BaseSearchResponse { }
lib/ExperianDataQuality/Common/Response/SearchResponse.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once "BaseSearchResponse.php";
3
+
4
+ /**
5
+ * Holds the refine response data from ProOnDemand WS.
6
+ */
7
+ class SearchResponse extends BaseSearchResponse { }
lib/ExperianDataQuality/DPVStatusType.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class DPVStatusType
3
+ {
4
+ const DPVNOTCONFIGURED = 'DPVNotConfigured';
5
+ const DPVCONFIGURED = 'DPVConfigured';
6
+ const DPVCONFIRMED = 'DPVConfirmed';
7
+ const DPVCONFIRMEDMISSINGSEC = 'DPVConfirmedMissingSec';
8
+ const DPVNOTCONFIRMED = 'DPVNotConfirmed';
9
+ const DPVLOCKED = 'DPVLocked';
10
+ const DPVSEEDHIT = 'DPVSeedHit';
11
+ }
lib/ExperianDataQuality/EngineEnumType.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EngineEnumType
3
+ {
4
+ const SINGLELINE = 'Singleline';
5
+ const TYPEDOWN = 'Typedown';
6
+ const VERIFICATION = 'Verification';
7
+ const KEYFINDER = 'Keyfinder';
8
+ const INTUITIVE = 'Intuitive';
9
+ }
lib/ExperianDataQuality/EngineType.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EngineType
3
+ {
4
+ public $EngineType = array();
5
+ public $PromptSet;
6
+ private $Flatten;
7
+ private $FlattenSpecified;
8
+ private $Intensity;
9
+ private $IntensitySpecified;
10
+ private $PromptSetSpecified;
11
+ private $Threshold;
12
+ private $Timeout;
13
+ private $Value;
14
+
15
+ public function __construct($flattenField, $promptSetFieldSpecified, $thresholdField, $timeoutField, $valueField, $flattenSpecified = \NULL, $intensity = \NULL, $intensitySpecified= \NULL)
16
+ {
17
+ $this->Value = $valueField;
18
+ $this->Flatten = $flattenField;
19
+ $this->PromptSetSpecified = $promptSetFieldSpecified;
20
+ $this->Threshold = $thresholdField;
21
+ $this->Timeout = $timeoutField;
22
+
23
+ if(isset($flattenSpecified))
24
+ {
25
+ $this->FlattenSpecified = $flattenSpecified;
26
+ }
27
+
28
+ if(isset($intensity))
29
+ {
30
+ $this->Intensity = $intensity;
31
+ }
32
+
33
+ if(isset($intensitySpecified))
34
+ {
35
+ $this->IntensitySpecified = $intensitySpecified;
36
+ }
37
+
38
+ $this->EngineType = array(
39
+ '_' => $this->Value,
40
+ 'Flatten' => $this->Flatten,
41
+ 'PromptSet' => $this->PromptSet
42
+ );
43
+ }
44
+ }
lib/ExperianDataQuality/IService.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/CanSearchRequest.php');
3
+ require_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetLayoutsRequest.php';
4
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/SearchRequest.php');
5
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/RefineRequest.php');
6
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/GetAddressRequest.php');
7
+ require_once(Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/Request/BaseSearchRequest.php');
8
+
9
+ interface ExperianDataQuality_IService
10
+ {
11
+ function doGetLayouts(GetLayoutsRequest $doGetLayoutsRequest);
12
+
13
+ function doCanSearch(CanSearchRequest $canSearchRequest);
14
+
15
+ function doSearch(BaseSearchRequest $baseRequest, $searchAddress = "");
16
+
17
+ function doRefine(RefineRequest $refineRequest);
18
+
19
+ function doGetAddress(GetAddressRequest $getAddressRequest);
20
+ }
lib/ExperianDataQuality/Layout.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Layout
3
+ {
4
+ public $Name;
5
+ public $Comment;
6
+
7
+ public function __construct($name, $comment)
8
+ {
9
+ $this->Name = $name;
10
+ $this->Comment = $comment;
11
+ }
12
+ }
lib/ExperianDataQuality/LineContentType.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LineContentType
3
+ {
4
+ const NONE = 'None';
5
+ const ADDRESS= 'Address';
6
+ const NAME = 'Name';
7
+ const ANCILLARY= 'Ancillary';
8
+ const DATAPLUS = 'DataPlus';
9
+ }
lib/ExperianDataQuality/Picklist.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'QAPicklist.php';
3
+
4
+ class Picklist
5
+ {
6
+ public $QAPicklist;
7
+
8
+ public function __construct($response)
9
+ {
10
+ $this->QAPicklist = isset($response->QAPicklist) ? new QAPicklist($response->QAPicklist) : \FALSE;
11
+ }
12
+ }
lib/ExperianDataQuality/PicklistEntry.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PicklistEntry
3
+ {
4
+ public $Moniker;
5
+ public $PartialAddress;
6
+ public $PickList;
7
+ public $Postcode;
8
+ public $Score;
9
+ public $FullAddress;
10
+ public $Multiples;
11
+ public $CanStep = \FALSE;
12
+ public $AliasMatch = \FALSE;
13
+ public $PostcodeRecoded = \FALSE;
14
+ public $CrossBorderMatch = \FALSE;
15
+ public $DummyPOBox = \FALSE;
16
+ public $Name = \FALSE;
17
+ public $Information = \FALSE;
18
+ public $WarnInformation = \FALSE;
19
+ public $IncompleteAddr = \FALSE;
20
+ public $UnresolvableRange;
21
+ public $PhantomPrimaryPoint = \FALSE;
22
+ public $SubsidiaryData = \FALSE;
23
+ public $ExtendedData = \FALSE;
24
+ public $EnhancedData = \FALSE;
25
+
26
+ public function __construct($response)
27
+ {
28
+ $this->Moniker = isset($response->Moniker) ? $response->Moniker : \FALSE;
29
+ $this->PartialAddress = isset($response->PartialAddress) ? $response->PartialAddress : \FALSE;
30
+ $this->PickList = isset($response->Picklist) ? $response->Picklist : \FALSE;
31
+ $this->Postcode = isset($response->Postcode) ? $response->Postcode : \FALSE;
32
+ $this->Score = isset($response->Score) ? $response->Score : \FALSE;
33
+ $this->FullAddress = isset($response->FullAddress) ? $response->FullAddress : \FALSE;
34
+ $this->UnresolvableRange = isset($response->UnresolvableRange) ? $response->UnresolvableRange : \FALSE;
35
+ }
36
+ }
lib/ExperianDataQuality/ProOnDemandService.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/GlobalSettings.php';
3
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
4
+
5
+ /**
6
+ * ProOnDemand service.
7
+ */
8
+ class ExperianDataQuality_ProOnDemandService extends ExperianDataQuality_BaseService implements ExperianDataQuality_IService
9
+ {
10
+ public function __construct($token = \NULL)
11
+ {
12
+ $wsdl = Mage::getBaseDir('lib') . '/ExperianDataQuality/ProOnDemandService.wsdl';
13
+
14
+ if(HelperMethods::isNullOrWhiteSpace($token))
15
+ {
16
+ $token = GlobalSettings::instance()->getOnDemandToken();
17
+ }
18
+
19
+ $context = array(
20
+ 'http' => array( 'header' => 'Auth-Token: ' . $token)
21
+ );
22
+
23
+ if(GlobalSettings::instance()->getIsUsingProxy())
24
+ {
25
+ $this->client = new \SoapClient($wsdl,
26
+ array(
27
+ 'soap_version' => SOAP_1_2,
28
+ 'trace' => \FALSE,
29
+ 'exceptions' => \TRUE,
30
+ 'stream_context' => stream_context_create($context),
31
+ 'proxy_host' => GlobalSettings::instance()->getProxyName(),
32
+ 'proxy_port' => GlobalSettings::instance()->getProxyPort(),
33
+ 'proxy_login' => GlobalSettings::instance()->getProxyUser(),
34
+ 'proxy_password' => GlobalSettings::instance()->getProxyPassword()));
35
+ }
36
+ else
37
+ {
38
+ $this->client = new \SoapClient($wsdl,
39
+ array(
40
+ 'soap_version' => SOAP_1_2,
41
+ 'trace' => \FALSE,
42
+ 'exceptions' => \TRUE,
43
+ 'stream_context' => stream_context_create($context)));
44
+ }
45
+
46
+ if (\is_soap_fault($this->client))
47
+ {
48
+ $this->client = \NULL;
49
+ }
50
+
51
+ parent::__construct();
52
+ }
53
+
54
+ protected function _setLocation($location = NULL)
55
+ {
56
+ if(HelperMethods::isNullOrWhiteSpace($location))
57
+ {
58
+ $location = GlobalSettings::instance()->getOnDemandEndpoint();
59
+ }
60
+
61
+ $this->client->__setLocation($location);
62
+ }
63
+ }
lib/ExperianDataQuality/ProOnDemandService.wsdl ADDED
@@ -0,0 +1,1081 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions name="QAS" targetNamespace="http://www.qas.com/OnDemand-2011-03" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:qas="http://www.qas.com/OnDemand-2011-03">
3
+ <types>
4
+ <xs:schema elementFormDefault="qualified" targetNamespace="http://www.qas.com/OnDemand-2011-03" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
5
+
6
+ <xs:import namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" />
7
+
8
+ <xs:complexType name="QAAuthentication">
9
+ <xs:sequence>
10
+ <xs:element minOccurs="1" maxOccurs="1" name="Username" type="xs:string"/>
11
+ <xs:element minOccurs="1" maxOccurs="1" name="Password" type="xs:string"/>
12
+ </xs:sequence>
13
+ </xs:complexType>
14
+ <xs:element name="QAAuthentication" type="qas:QAAuthentication"/>
15
+
16
+ <xs:complexType name="QAQueryHeader">
17
+ <xs:sequence minOccurs="1" maxOccurs="1">
18
+ <xs:element name="QAAuthentication" type="qas:QAAuthentication"/>
19
+ <xs:element name="Security" type="wsse:SecurityHeaderType"/>
20
+ </xs:sequence>
21
+ </xs:complexType>
22
+ <xs:element name="QAQueryHeader" type="qas:QAQueryHeader"/>
23
+
24
+ <xs:complexType name="QAInformation">
25
+ <xs:sequence>
26
+ <xs:element minOccurs="1" maxOccurs="1" name="StateTransition" type="xs:string"/>
27
+ <xs:element minOccurs="1" maxOccurs="1" name="CreditsUsed" type="xs:long"/>
28
+ </xs:sequence>
29
+ </xs:complexType>
30
+ <xs:element name="QAInformation" type="qas:QAInformation"/>
31
+
32
+ <xs:simpleType name="RequestTagType">
33
+ <xs:annotation>
34
+ <xs:documentation>RequestTagType defines a transaction(s) identifier</xs:documentation>
35
+ </xs:annotation>
36
+ <xs:restriction base="xs:string">
37
+ <xs:pattern value="^[A-Za-z0-9\\\ /._:-]{0,256}$"/>
38
+ </xs:restriction>
39
+ </xs:simpleType>
40
+
41
+ <xs:element name="QASearch">
42
+ <xs:annotation>
43
+ <xs:documentation>QASearch defines a search request</xs:documentation>
44
+ <xs:documentation>The child elements are as follows:</xs:documentation>
45
+ <xs:documentation>Country : The country dataset to use</xs:documentation>
46
+ <xs:documentation>Engine : The search engine to use, and any engine specific configuration settings</xs:documentation>
47
+ <xs:documentation>Layout : The layout to use when creating a formatted address (required by verification engine only)</xs:documentation>
48
+ <xs:documentation>Search : The actual search string</xs:documentation>
49
+ <xs:documentation>FormattedAddressInPicklist: Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
50
+ <xs:documentation>RequestTag : String for marking request</xs:documentation>
51
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
52
+ </xs:annotation>
53
+ <xs:complexType>
54
+ <xs:sequence>
55
+ <xs:element name="Country" type="qas:DataIDType"/>
56
+ <xs:element name="Engine" type="qas:EngineType"/>
57
+ <xs:element name="Layout" type="xs:string" minOccurs="0"/>
58
+ <xs:element name="Search" type="xs:string"/>
59
+ <xs:element name="FormattedAddressInPicklist" type="xs:boolean" default="false" minOccurs="0"/>
60
+ </xs:sequence>
61
+ <xs:attribute name="Localisation" type="xs:string"/>
62
+ <xs:attribute name="RequestTag" type="qas:RequestTagType"/>
63
+ </xs:complexType>
64
+ </xs:element>
65
+
66
+
67
+ <xs:simpleType name="DataIDType">
68
+ <xs:annotation>
69
+ <xs:documentation>DataIDType defines a data identifier, a 3 charater code</xs:documentation>
70
+ </xs:annotation>
71
+ <xs:restriction base="xs:string">
72
+ <xs:pattern value="[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]"/>
73
+ </xs:restriction>
74
+ </xs:simpleType>
75
+
76
+ <xs:complexType name="EngineType">
77
+ <xs:annotation>
78
+ <xs:documentation>EngineType specifies the engine to use for a search, and any engine options</xs:documentation>
79
+ <xs:documentation>The various attributes are as follows:</xs:documentation>
80
+ <xs:documentation>Flatten : Whether or not to flatten the picklist returned by the search</xs:documentation>
81
+ <xs:documentation>Intensity : How hard the search engine will search to get a match</xs:documentation>
82
+ <xs:documentation>PromptSet : The prompt set to apply to the search string</xs:documentation>
83
+ <xs:documentation>Threshold : The typedown threshold (typedown engine only)</xs:documentation>
84
+ <xs:documentation>Timeout : The time out period in milliseconds</xs:documentation>
85
+ </xs:annotation>
86
+ <xs:simpleContent>
87
+ <xs:extension base="qas:EngineEnumType">
88
+ <xs:attribute name="Flatten" type="xs:boolean"/>
89
+ <xs:attribute name="Intensity" type="qas:EngineIntensityType"/>
90
+ <xs:attribute name="PromptSet" type="qas:PromptSetType"/>
91
+ <xs:attribute name="Threshold" type="qas:ThresholdType"/>
92
+ <xs:attribute name="Timeout" type="qas:TimeoutType"/>
93
+ </xs:extension>
94
+ </xs:simpleContent>
95
+ </xs:complexType>
96
+
97
+ <xs:simpleType name="EngineEnumType">
98
+ <xs:annotation>
99
+ <xs:documentation>The available engines</xs:documentation>
100
+ </xs:annotation>
101
+ <xs:restriction base="xs:string">
102
+ <xs:enumeration value="Singleline"/>
103
+ <xs:enumeration value="Typedown"/>
104
+ <xs:enumeration value="Verification"/>
105
+ <xs:enumeration value="Keyfinder"/>
106
+ <xs:enumeration value="Intuitive"/>
107
+ </xs:restriction>
108
+ </xs:simpleType>
109
+
110
+ <xs:simpleType name="ThresholdType">
111
+ <xs:annotation>
112
+ <xs:documentation>The picklist threshold - the maximum size of the picklist</xs:documentation>
113
+ </xs:annotation>
114
+ <xs:restriction base="xs:positiveInteger">
115
+ <xs:minInclusive value="5"/>
116
+ <xs:maxInclusive value="750"/>
117
+ </xs:restriction>
118
+ </xs:simpleType>
119
+
120
+ <xs:simpleType name="EngineIntensityType">
121
+ <xs:annotation>
122
+ <xs:documentation>The available searching intensity levels</xs:documentation>
123
+ </xs:annotation>
124
+ <xs:restriction base="xs:string">
125
+ <xs:enumeration value="Exact"/>
126
+ <xs:enumeration value="Close"/>
127
+ <xs:enumeration value="Extensive"/>
128
+ </xs:restriction>
129
+ </xs:simpleType>
130
+
131
+ <xs:simpleType name="TimeoutType">
132
+ <xs:annotation>
133
+ <xs:documentation>The server searching timeout - how long before a search is aborted (milliseconds)</xs:documentation>
134
+ </xs:annotation>
135
+ <xs:restriction base="xs:nonNegativeInteger">
136
+ <xs:minInclusive value="0"/>
137
+ <xs:maxInclusive value="600000"/>
138
+ </xs:restriction>
139
+ </xs:simpleType>
140
+
141
+ <xs:simpleType name="PromptSetType">
142
+ <xs:annotation>
143
+ <xs:documentation>The available prompt sets</xs:documentation>
144
+ </xs:annotation>
145
+ <xs:restriction base="xs:string">
146
+ <xs:enumeration value="OneLine"/>
147
+ <xs:enumeration value="Default"/>
148
+ <xs:enumeration value="Generic"/>
149
+ <xs:enumeration value="Optimal"/>
150
+ <xs:enumeration value="Alternate"/>
151
+ <xs:enumeration value="Alternate2"/>
152
+ <xs:enumeration value="Alternate3"/>
153
+ </xs:restriction>
154
+ </xs:simpleType>
155
+
156
+ <xs:element name="QASearchResult">
157
+ <xs:annotation>
158
+ <xs:documentation>QASearchResult describes the results of a search</xs:documentation>
159
+ <xs:documentation>The child elements are as follows:</xs:documentation>
160
+ <xs:documentation>QAPicklist : The picklist produced by the search</xs:documentation>
161
+ <xs:documentation>
162
+ QAAddress : A formatted address produced by the search.
163
+ Note that only the verification engine will ever produce a formatted address.
164
+ Other engines will only ever produce a picklist.
165
+ </xs:documentation>
166
+ <xs:documentation>VerificationFlags : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
167
+ <xs:documentation>
168
+ The VerifyLevel attribute specifies the level to which the verification engine has
169
+ verified the input address. It can be ignored when using all other engines.
170
+ </xs:documentation>
171
+ </xs:annotation>
172
+ <xs:complexType>
173
+ <xs:sequence>
174
+ <xs:element name="QAPicklist" type="qas:QAPicklistType" minOccurs="0"/>
175
+ <xs:element name="QAAddress" type="qas:QAAddressType" minOccurs="0"/>
176
+ <xs:element name="VerificationFlags" type="qas:VerificationFlagsType" minOccurs="0"/>
177
+ </xs:sequence>
178
+ <xs:attribute name="VerifyLevel" type="qas:VerifyLevelType" default="None"/>
179
+ </xs:complexType>
180
+ </xs:element>
181
+
182
+ <xs:simpleType name="VerifyLevelType">
183
+ <xs:annotation>
184
+ <xs:documentation>The possible verification levels</xs:documentation>
185
+ </xs:annotation>
186
+ <xs:restriction base="xs:string">
187
+ <xs:enumeration value="None"/>
188
+ <xs:enumeration value="Verified"/>
189
+ <xs:enumeration value="InteractionRequired"/>
190
+ <xs:enumeration value="PremisesPartial"/>
191
+ <xs:enumeration value="StreetPartial"/>
192
+ <xs:enumeration value="Multiple"/>
193
+ <xs:enumeration value="VerifiedPlace"/>
194
+ <xs:enumeration value="VerifiedStreet"/>
195
+ </xs:restriction>
196
+ </xs:simpleType>
197
+
198
+ <xs:element name="QARefine">
199
+ <xs:annotation>
200
+ <xs:documentation>QARefine defines a refinement request</xs:documentation>
201
+ <xs:documentation>The child elements are as follows:</xs:documentation>
202
+ <xs:documentation>Moniker : The Search Point Moniker to refine</xs:documentation>
203
+ <xs:documentation>Refinement : The refinement text</xs:documentation>
204
+ <xs:documentation>Layout : The layout to use when creating a formatted address (used in certain scenarios for formatting picklist text)</xs:documentation>
205
+ <xs:documentation>FormattedAddressInPicklist: Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
206
+ <xs:documentation>The attributes are as follows:</xs:documentation>
207
+ <xs:documentation>Threshold : The picklist threshold (i.e. the maximum size of the picklist)</xs:documentation>
208
+ <xs:documentation>Timeout : The timeout period in milliseconds</xs:documentation>
209
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
210
+ <xs:documentation>RequestTag : String for marking request</xs:documentation>
211
+ </xs:annotation>
212
+ <xs:complexType>
213
+ <xs:sequence>
214
+ <xs:element name="Moniker" type="xs:string"/>
215
+ <xs:element name="Refinement" type="xs:string"/>
216
+ <xs:element name="Layout" type="xs:string" minOccurs="0"/>
217
+ <xs:element name="FormattedAddressInPicklist" type="xs:boolean" default="false" minOccurs="0"/>
218
+ </xs:sequence>
219
+ <xs:attribute name="Threshold" type="qas:ThresholdType"/>
220
+ <xs:attribute name="Timeout" type="qas:TimeoutType"/>
221
+ <xs:attribute name="Localisation" type="xs:string"/>
222
+ <xs:attribute name="RequestTag" type="qas:RequestTagType"/>
223
+ </xs:complexType>
224
+ </xs:element>
225
+
226
+ <xs:element name="Picklist">
227
+ <xs:annotation>
228
+ <xs:documentation>Picklist describes a returned picklist</xs:documentation>
229
+ </xs:annotation>
230
+ <xs:complexType>
231
+ <xs:sequence>
232
+ <xs:element name="QAPicklist" type="qas:QAPicklistType"/>
233
+ </xs:sequence>
234
+ </xs:complexType>
235
+ </xs:element>
236
+
237
+ <xs:complexType name="QAPicklistType">
238
+ <xs:annotation>
239
+ <xs:documentation>QAPicklistType describes a picklist</xs:documentation>
240
+ <xs:documentation>The child elements are as follows:</xs:documentation>
241
+ <xs:documentation>FullPicklistMoniker : The Search Point Moniker that describes the entire picklist</xs:documentation>
242
+ <xs:documentation>PicklistEntry : The actual picklist entries</xs:documentation>
243
+ <xs:documentation>Prompt : The prompt to display to the user, indicating what information they should enter next</xs:documentation>
244
+ <xs:documentation>Total : The total number of available results</xs:documentation>
245
+ <xs:documentation>The attributes are as follows:</xs:documentation>
246
+ <xs:documentation>AutoFormatSafe : It is suggested that you immediately format the first picklist item</xs:documentation>
247
+ <xs:documentation>AutoFormatPastClose : There is only one exact match, so you may want immediately to format the first picklist item</xs:documentation>
248
+ <xs:documentation>AutoStepInSafe : It is suggested that you immediately step-in to the first picklist item</xs:documentation>
249
+ <xs:documentation>AutoStepInPastClose : There is only one exact match, so you may want immediately to step-in to the first picklist item</xs:documentation>
250
+ <xs:documentation>LargePotential : Potentially, there are too many results to display</xs:documentation>
251
+ <xs:documentation>MaxMatches : The number of results exceeded the maximum allowed</xs:documentation>
252
+ <xs:documentation>MoreOtherMatches : There are additional matches that can be displayed</xs:documentation>
253
+ <xs:documentation>OverThreshold : There are more picklist items than the threshold value</xs:documentation>
254
+ <xs:documentation>Timeout : The search/refinement timed out</xs:documentation>
255
+ </xs:annotation>
256
+ <xs:sequence>
257
+ <xs:element name="FullPicklistMoniker" type="xs:string"/>
258
+ <xs:element name="PicklistEntry" type="qas:PicklistEntryType" minOccurs="0" maxOccurs="unbounded"/>
259
+ <xs:element name="Prompt" type="xs:string"/>
260
+ <xs:element name="Total" type="xs:nonNegativeInteger"/>
261
+ </xs:sequence>
262
+ <xs:attribute name="AutoFormatSafe" type="xs:boolean" default="false"/>
263
+ <xs:attribute name="AutoFormatPastClose" type="xs:boolean" default="false"/>
264
+ <xs:attribute name="AutoStepinSafe" type="xs:boolean" default="false"/>
265
+ <xs:attribute name="AutoStepinPastClose" type="xs:boolean" default="false"/>
266
+ <xs:attribute name="LargePotential" type="xs:boolean" default="false"/>
267
+ <xs:attribute name="MaxMatches" type="xs:boolean" default="false"/>
268
+ <xs:attribute name="MoreOtherMatches" type="xs:boolean" default="false"/>
269
+ <xs:attribute name="OverThreshold" type="xs:boolean" default="false"/>
270
+ <xs:attribute name="Timeout" type="xs:boolean" default="false"/>
271
+ </xs:complexType>
272
+
273
+ <xs:complexType name="PicklistEntryType">
274
+ <xs:annotation>
275
+ <xs:documentation>PicklistEntryType describes an entry in a picklist</xs:documentation>
276
+ <xs:documentation>The child elements are as follows:</xs:documentation>
277
+ <xs:documentation>Moniker : The Search Point Moniker that represents this picklist entry</xs:documentation>
278
+ <xs:documentation>PartialAddress : The full details of the address captured so far</xs:documentation>
279
+ <xs:documentation>Picklist : The picklist text to display</xs:documentation>
280
+ <xs:documentation>Postcode : The postcode to display</xs:documentation>
281
+ <xs:documentation>Score : The percentage score assigned to the match</xs:documentation>
282
+ <xs:documentation>QAAddress : The Full Address for the moniker</xs:documentation>
283
+ <xs:documentation>The attributes are as follows:</xs:documentation>
284
+ <xs:documentation>FullAddress : This picklist entry is a full deliverable address</xs:documentation>
285
+ <xs:documentation>Multiples : This entry represents multiple address lines</xs:documentation>
286
+ <xs:documentation>CanStep : This entry can be stepped into</xs:documentation>
287
+ <xs:documentation>AliasMatch : This match is an alias</xs:documentation>
288
+ <xs:documentation>PostcodeRecoded : This entry has a recoded postcode</xs:documentation>
289
+ <xs:documentation>CrossBorderMatch : This entry represents a nearby area, outside the strict initial boundaries of the search</xs:documentation>
290
+ <xs:documentation>DummyPOBox : This entry is the dummy PO Box entry</xs:documentation>
291
+ <xs:documentation>Name : This entry is a Names result</xs:documentation>
292
+ <xs:documentation>Information : This entry is an informational prompt</xs:documentation>
293
+ <xs:documentation>WarnInformation : This entry is a warning informational prompt</xs:documentation>
294
+ <xs:documentation>IncompleteAddr : This entry is the dummy item (for premise-less countries)</xs:documentation>
295
+ <xs:documentation>UnresolvableRange : This entry is a static range item that cannot be expanded</xs:documentation>
296
+ <xs:documentation>PhantomPrimaryPoint : This entry is a Phantom Primary Point (AUS only)</xs:documentation>
297
+ <xs:documentation>SubsidiaryData : This entry is from the subsidiary rather than the base dataset</xs:documentation>
298
+ <xs:documentation>ExtendedData : This entry is from the base dataset but extended by the subsidiary dataset</xs:documentation>
299
+ <xs:documentation>EnhancedData : This entry is from the base dataset but enhanced by the subsidiary data set</xs:documentation>
300
+ </xs:annotation>
301
+ <xs:sequence>
302
+ <xs:element name="Moniker" type="xs:string"/>
303
+ <xs:element name="PartialAddress" type="xs:string"/>
304
+ <xs:element name="Picklist" type="xs:string"/>
305
+ <xs:element name="Postcode" type="xs:string"/>
306
+ <xs:element name="Score" type="xs:nonNegativeInteger"/>
307
+ <xs:element name="QAAddress" type="qas:QAAddressType" minOccurs="0"/>
308
+ </xs:sequence>
309
+ <xs:attribute name="FullAddress" type="xs:boolean" default="false"/>
310
+ <xs:attribute name="Multiples" type="xs:boolean" default="false"/>
311
+ <xs:attribute name="CanStep" type="xs:boolean" default="false"/>
312
+ <xs:attribute name="AliasMatch" type="xs:boolean" default="false"/>
313
+ <xs:attribute name="PostcodeRecoded" type="xs:boolean" default="false"/>
314
+ <xs:attribute name="CrossBorderMatch" type="xs:boolean" default="false"/>
315
+ <xs:attribute name="DummyPOBox" type="xs:boolean" default="false"/>
316
+ <xs:attribute name="Name" type="xs:boolean" default="false"/>
317
+ <xs:attribute name="Information" type="xs:boolean" default="false"/>
318
+ <xs:attribute name="WarnInformation" type="xs:boolean" default="false"/>
319
+ <xs:attribute name="IncompleteAddr" type="xs:boolean" default="false"/>
320
+ <xs:attribute name="UnresolvableRange" type="xs:boolean" default="false"/>
321
+ <xs:attribute name="PhantomPrimaryPoint" type="xs:boolean" default="false"/>
322
+ <xs:attribute name="SubsidiaryData" type="xs:boolean" default="false"/>
323
+ <xs:attribute name="ExtendedData" type="xs:boolean" default="false"/>
324
+ <xs:attribute name="EnhancedData" type="xs:boolean" default="false"/>
325
+ </xs:complexType>
326
+
327
+ <xs:element name="QAGetAddress">
328
+ <xs:annotation>
329
+ <xs:documentation>QAGetAddress defines a request for a formatted address</xs:documentation>
330
+ <xs:documentation>The child elements are as follows:</xs:documentation>
331
+ <xs:documentation>Layout : The layout to use</xs:documentation>
332
+ <xs:documentation>Moniker : The Search Point Moniker of the picklist entry to format</xs:documentation>
333
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
334
+ <xs:documentation>RequestTag : String for marking request</xs:documentation>
335
+ </xs:annotation>
336
+ <xs:complexType>
337
+ <xs:sequence>
338
+ <xs:element name="Layout" type="xs:string" minOccurs="0"/>
339
+ <xs:element name="Moniker" type="xs:string"/>
340
+ </xs:sequence>
341
+ <xs:attribute name="Localisation" type="xs:string"/>
342
+ <xs:attribute name="RequestTag" type="qas:RequestTagType"/>
343
+ </xs:complexType>
344
+ </xs:element>
345
+
346
+ <xs:element name="Address">
347
+ <xs:complexType>
348
+ <xs:sequence>
349
+ <xs:element name="QAAddress" type="qas:QAAddressType"/>
350
+ </xs:sequence>
351
+ </xs:complexType>
352
+ </xs:element>
353
+
354
+ <xs:complexType name="QAAddressType">
355
+ <xs:annotation>
356
+ <xs:documentation>QAAddressType describes a formatted address</xs:documentation>
357
+ <xs:documentation>The child elements are as follows:</xs:documentation>
358
+ <xs:documentation>AddressLine : The individual lines of the address</xs:documentation>
359
+ <xs:documentation>The attributes are as follows:</xs:documentation>
360
+ <xs:documentation>Overflow : There are not enough address lines configured to display the whole address</xs:documentation>
361
+ <xs:documentation>Truncated : Truncation has occurred on one or more address lines</xs:documentation>
362
+ <xs:documentation>DPVStatus : DPV Status for the Address</xs:documentation>
363
+ <xs:documentation>MissingSubPremise: Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
364
+ </xs:annotation>
365
+ <xs:sequence>
366
+ <xs:element name="AddressLine" type="qas:AddressLineType" maxOccurs="unbounded"/>
367
+ </xs:sequence>
368
+ <xs:attribute name="Overflow" type="xs:boolean" default="false"/>
369
+ <xs:attribute name="Truncated" type="xs:boolean" default="false"/>
370
+ <xs:attribute name="DPVStatus" type="qas:DPVStatusType"/>
371
+ <xs:attribute name="MissingSubPremise" type="xs:boolean" default="false"/>
372
+ </xs:complexType>
373
+ <xs:annotation>
374
+ <xs:documentation>DPVStatusType specifies the DPVStatus for an Address</xs:documentation>
375
+ <xs:documentation>The various attributes are as follows:</xs:documentation>
376
+ <xs:documentation>DPVNotConfigured : DPV has not been configured in the Layout</xs:documentation>
377
+ <xs:documentation>DPVConfigured : DPV has been configured in the Layout</xs:documentation>
378
+ <xs:documentation>DPVConfirmed : The Address is DPV Confirmed</xs:documentation>
379
+ <xs:documentation>DPVConfirmedMissingSec : The Address is DPV Confirmed but has Missing or Incorrect secondary information</xs:documentation>
380
+ <xs:documentation>DPVNotConfirmed : The Address is NOT DPV Confirmed</xs:documentation>
381
+ <xs:documentation>DPVLocked : DPV Address Detail Retrieval is Locked</xs:documentation>
382
+ <xs:documentation>DPVSeedHit : The Address is a DPV Seed</xs:documentation>
383
+ </xs:annotation>
384
+ <xs:simpleType name="DPVStatusType">
385
+ <xs:restriction base="xs:string">
386
+ <xs:enumeration value="DPVNotConfigured"/>
387
+ <xs:enumeration value="DPVConfigured"/>
388
+ <xs:enumeration value="DPVConfirmed"/>
389
+ <xs:enumeration value="DPVConfirmedMissingSec"/>
390
+ <xs:enumeration value="DPVNotConfirmed"/>
391
+ <xs:enumeration value="DPVLocked"/>
392
+ <xs:enumeration value="DPVSeedHit"/>
393
+ </xs:restriction>
394
+ </xs:simpleType>
395
+ <xs:complexType name="AddressLineType">
396
+ <xs:annotation>
397
+ <xs:documentation>AddressLineType describes one line of a formatted address</xs:documentation>
398
+ <xs:documentation>The child elements are as follows:</xs:documentation>
399
+ <xs:documentation>Label : The name of any address element fixed to this line</xs:documentation>
400
+ <xs:documentation>Line : The formatted address line</xs:documentation>
401
+ <xs:documentation>DataplusGroup: DataPlus groups associated with this line</xs:documentation>
402
+ <xs:documentation>The attributes are as follows:</xs:documentation>
403
+ <xs:documentation>LineContent : The type of data on this line</xs:documentation>
404
+ <xs:documentation>Overflow : Some address elements were lost from this line</xs:documentation>
405
+ <xs:documentation>Truncated : Truncation occurred on this line</xs:documentation>
406
+ </xs:annotation>
407
+ <xs:sequence>
408
+ <xs:element name="Label" type="xs:string" minOccurs="0"/>
409
+ <xs:element name="Line" type="xs:string" minOccurs="0"/>
410
+ <xs:element name="DataplusGroup" type="qas:DataplusGroupType" minOccurs="0" maxOccurs="unbounded"/>
411
+ </xs:sequence>
412
+ <xs:attribute name="LineContent" type="qas:LineContentType" default="Address"/>
413
+ <xs:attribute name="Overflow" type="xs:boolean" default="false"/>
414
+ <xs:attribute name="Truncated" type="xs:boolean" default="false"/>
415
+ </xs:complexType>
416
+
417
+ <xs:complexType name="DataplusGroupType">
418
+ <xs:sequence>
419
+ <xs:element name="DataplusGroupItem" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
420
+ </xs:sequence>
421
+ <xs:attribute name="GroupName" type="xs:string"/>
422
+ </xs:complexType>
423
+
424
+ <xs:simpleType name="LineContentType">
425
+ <xs:restriction base="xs:string">
426
+ <xs:enumeration value="None"/>
427
+ <xs:enumeration value="Address"/>
428
+ <xs:enumeration value="Name"/>
429
+ <xs:enumeration value="Ancillary"/>
430
+ <xs:enumeration value="DataPlus"/>
431
+ </xs:restriction>
432
+ </xs:simpleType>
433
+
434
+ <xs:element name="QAData">
435
+ <xs:annotation>
436
+ <xs:documentation>QAData describes all of the datasets that are available</xs:documentation>
437
+ <xs:documentation>DataSet : Details of a dataset</xs:documentation>
438
+ </xs:annotation>
439
+ <xs:complexType>
440
+ <xs:sequence>
441
+ <xs:element name="DataSet" type="qas:QADataSet" minOccurs="0" maxOccurs="unbounded"/>
442
+ </xs:sequence>
443
+ </xs:complexType>
444
+ </xs:element>
445
+
446
+ <xs:complexType name="QADataSet">
447
+ <xs:annotation>
448
+ <xs:documentation>QADataSet describes a dataset</xs:documentation>
449
+ <xs:documentation>Child elements are as follows:</xs:documentation>
450
+ <xs:documentation>ID : Three letter dataset ID</xs:documentation>
451
+ <xs:documentation>Name : Full name of dataset</xs:documentation>
452
+ </xs:annotation>
453
+ <xs:sequence>
454
+ <xs:element name="ID" type="qas:DataIDType"/>
455
+ <xs:element name="Name" type="xs:string"/>
456
+ </xs:sequence>
457
+ </xs:complexType>
458
+
459
+ <xs:element name="QAGetData">
460
+ <xs:annotation>
461
+ <xs:documentation>QAGetData defines a data for GetData message</xs:documentation>
462
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
463
+ </xs:annotation>
464
+ <xs:complexType>
465
+ <xs:sequence>
466
+ </xs:sequence>
467
+ <xs:attribute name="Localisation" type="xs:string"/>
468
+ </xs:complexType>
469
+ </xs:element>
470
+
471
+ <xs:element name="QAGetLicenseInfo">
472
+ <xs:annotation>
473
+ <xs:documentation>QAGetLicenseInfo defines a data for the GetLicenseInfo message</xs:documentation>
474
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
475
+ </xs:annotation>
476
+ <xs:complexType>
477
+ <xs:sequence>
478
+ </xs:sequence>
479
+ <xs:attribute name="Localisation" type="xs:string"/>
480
+ </xs:complexType>
481
+ </xs:element>
482
+
483
+ <xs:element name="QAGetSystemInfo">
484
+ <xs:annotation>
485
+ <xs:documentation>QAGetSystemInfo a data for the GetSystemInfo message</xs:documentation>
486
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
487
+ </xs:annotation>
488
+ <xs:complexType>
489
+ <xs:sequence>
490
+ </xs:sequence>
491
+ <xs:attribute name="Localisation" type="xs:string"/>
492
+ </xs:complexType>
493
+ </xs:element>
494
+
495
+ <xs:element name="QAGetDataMapDetail">
496
+ <xs:annotation>
497
+ <xs:documentation>QAGetDataMapDetail describes a request for data map detail information</xs:documentation>
498
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
499
+ </xs:annotation>
500
+ <xs:complexType>
501
+ <xs:sequence>
502
+ <xs:element name="DataMap" type="qas:DataIDType"/>
503
+ </xs:sequence>
504
+ <xs:attribute name="Localisation" type="xs:string"/>
505
+ </xs:complexType>
506
+ </xs:element>
507
+
508
+ <xs:element name="QADataMapDetail">
509
+ <xs:annotation>
510
+ <xs:documentation>QADataMapDetail contains details of all datasets in a given data map</xs:documentation>
511
+ </xs:annotation>
512
+ <xs:complexType>
513
+ <xs:sequence>
514
+ <xs:element name="WarningLevel" type="qas:LicenceWarningLevel"/>
515
+ <xs:element name="LicensedSet" type="qas:QALicensedSet" minOccurs="0" maxOccurs="unbounded"/>
516
+ </xs:sequence>
517
+ </xs:complexType>
518
+ </xs:element>
519
+
520
+ <xs:element name="QALicenceInfo">
521
+ <xs:annotation>
522
+ <xs:documentation>QALicenceInfo describes all of the licence information for each dataset</xs:documentation>
523
+ <xs:documentation>Child elements are as follows:</xs:documentation>
524
+ <xs:documentation>WarningLevel : Warning level for the set of licensed data</xs:documentation>
525
+ <xs:documentation>LicensedSet : Details of a licensed dataset</xs:documentation>
526
+ </xs:annotation>
527
+ <xs:complexType>
528
+ <xs:sequence>
529
+ <xs:element name="WarningLevel" type="qas:LicenceWarningLevel"/>
530
+ <xs:element name="LicensedSet" type="qas:QALicensedSet" minOccurs="0" maxOccurs="unbounded"/>
531
+ </xs:sequence>
532
+ </xs:complexType>
533
+ </xs:element>
534
+
535
+ <xs:simpleType name="LicenceWarningLevel">
536
+ <xs:restriction base="xs:string">
537
+ <xs:enumeration value="None"/>
538
+ <xs:enumeration value="DataExpiring"/>
539
+ <xs:enumeration value="LicenceExpiring"/>
540
+ <xs:enumeration value="ClicksLow"/>
541
+ <xs:enumeration value="Evaluation"/>
542
+ <xs:enumeration value="NoClicks"/>
543
+ <xs:enumeration value="DataExpired"/>
544
+ <xs:enumeration value="EvalLicenceExpired"/>
545
+ <xs:enumeration value="FullLicenceExpired"/>
546
+ <xs:enumeration value="LicenceNotFound"/>
547
+ <xs:enumeration value="DataUnreadable"/>
548
+ </xs:restriction>
549
+ </xs:simpleType>
550
+
551
+ <xs:complexType name="QALicensedSet">
552
+ <xs:annotation>
553
+ <xs:documentation>QALicensedSet describes a licensed dataset</xs:documentation>
554
+ <xs:documentation>Child elements are as follows:</xs:documentation>
555
+ <xs:documentation>ID : Dataset ID</xs:documentation>
556
+ <xs:documentation>Description : Full description of dataset</xs:documentation>
557
+ <xs:documentation>Copyright : Copyright information</xs:documentation>
558
+ <xs:documentation>Version : Version of the data</xs:documentation>
559
+ <xs:documentation>BaseCountry : Data ID of the country to which this dataset is an extension</xs:documentation>
560
+ <xs:documentation>Status : A string describing the state of the data</xs:documentation>
561
+ <xs:documentation>Server : The name of the server where the dataset is being used</xs:documentation>
562
+ <xs:documentation>WarningLevel : The warning level for the dataset</xs:documentation>
563
+ <xs:documentation>DaysLeft : The number of days before the dataset is unusable</xs:documentation>
564
+ <xs:documentation>DaysLeft : The number of days before the dataset is unusable</xs:documentation>
565
+ <xs:documentation>LicenceDaysLeft : The number of days before the licence expires</xs:documentation>
566
+ </xs:annotation>
567
+ <xs:sequence>
568
+ <xs:element name="ID" type="xs:string"/>
569
+ <xs:element name="Description" type="xs:string"/>
570
+ <xs:element name="Copyright" type="xs:string"/>
571
+ <xs:element name="Version" type="xs:string"/>
572
+ <xs:element name="BaseCountry" type="xs:string"/>
573
+ <xs:element name="Status" type="xs:string"/>
574
+ <xs:element name="Server" type="xs:string"/>
575
+ <xs:element name="WarningLevel" type="qas:LicenceWarningLevel"/>
576
+ <xs:element name="DaysLeft" type="xs:nonNegativeInteger"/>
577
+ <xs:element name="DataDaysLeft" type="xs:nonNegativeInteger"/>
578
+ <xs:element name="LicenceDaysLeft" type="xs:nonNegativeInteger"/>
579
+ </xs:sequence>
580
+ </xs:complexType>
581
+
582
+ <xs:element name="QASystemInfo">
583
+ <xs:annotation>
584
+ <xs:documentation>QASystemInfo describes the current state of the system</xs:documentation>
585
+ </xs:annotation>
586
+ <xs:complexType>
587
+ <xs:sequence>
588
+ <xs:element name="SystemInfo" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
589
+ </xs:sequence>
590
+ </xs:complexType>
591
+ </xs:element>
592
+
593
+ <xs:element name="QAGetExampleAddresses">
594
+ <xs:annotation>
595
+ <xs:documentation>QAGetExampleAddresses defines a request for the example addresses for a given dataset</xs:documentation>
596
+ <xs:documentation>Child elements are as follows:</xs:documentation>
597
+ <xs:documentation>Country : The country dataset to get example addresses for</xs:documentation>
598
+ <xs:documentation>Layout : The layout to use to format the example addresses</xs:documentation>
599
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
600
+ <xs:documentation>RequestTag : String for marking request</xs:documentation>
601
+ </xs:annotation>
602
+ <xs:complexType>
603
+ <xs:sequence>
604
+ <xs:element name="Country" type="qas:DataIDType"/>
605
+ <xs:element name="Layout" type="xs:string"/>
606
+ </xs:sequence>
607
+ <xs:attribute name="Localisation" type="xs:string"/>
608
+ <xs:attribute name="RequestTag" type="qas:RequestTagType"/>
609
+ </xs:complexType>
610
+ </xs:element>
611
+
612
+ <xs:element name="QAExampleAddresses">
613
+ <xs:annotation>
614
+ <xs:documentation>QAExampleAddresses describes all of the example addresses for a dataset</xs:documentation>
615
+ </xs:annotation>
616
+ <xs:complexType>
617
+ <xs:sequence>
618
+ <xs:element name="ExampleAddress" type="qas:QAExampleAddress" minOccurs="0" maxOccurs="unbounded"/>
619
+ </xs:sequence>
620
+ </xs:complexType>
621
+ </xs:element>
622
+
623
+ <xs:complexType name="QAExampleAddress">
624
+ <xs:annotation>
625
+ <xs:documentation>QAExampleAddress describes an example address</xs:documentation>
626
+ <xs:documentation>Child elements are as follows:</xs:documentation>
627
+ <xs:documentation>Address : The formatted example address</xs:documentation>
628
+ <xs:documentation>Comment : A comment describing the address</xs:documentation>
629
+ </xs:annotation>
630
+ <xs:sequence>
631
+ <xs:element name="Address" type="qas:QAAddressType"/>
632
+ <xs:element name="Comment" type="xs:string"/>
633
+ </xs:sequence>
634
+ </xs:complexType>
635
+
636
+ <xs:element name="QAGetLayouts">
637
+ <xs:annotation>
638
+ <xs:documentation>QAGetLayouts defines a request for a list of all the available layouts</xs:documentation>
639
+ <xs:documentation>Child elements are as follows:</xs:documentation>
640
+ <xs:documentation>Country : The country dataset to get layouts for</xs:documentation>
641
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
642
+ </xs:annotation>
643
+ <xs:complexType>
644
+ <xs:sequence>
645
+ <xs:element name="Country" type="qas:DataIDType"/>
646
+ </xs:sequence>
647
+ <xs:attribute name="Localisation" type="xs:string"/>
648
+ </xs:complexType>
649
+ </xs:element>
650
+
651
+ <xs:element name="QALayouts">
652
+ <xs:annotation>
653
+ <xs:documentation>QALayouts describes all the available layouts for a dataset</xs:documentation>
654
+ </xs:annotation>
655
+ <xs:complexType>
656
+ <xs:sequence>
657
+ <xs:element name="Layout" type="qas:QALayout" minOccurs="0" maxOccurs="unbounded"/>
658
+ </xs:sequence>
659
+ </xs:complexType>
660
+ </xs:element>
661
+
662
+ <xs:complexType name="QALayout">
663
+ <xs:annotation>
664
+ <xs:documentation>QALayout describes a layout</xs:documentation>
665
+ <xs:documentation>Child elements are as follows:</xs:documentation>
666
+ <xs:documentation>Name : The name of the layout</xs:documentation>
667
+ <xs:documentation>Comment : A comment describing the layout</xs:documentation>
668
+ </xs:annotation>
669
+ <xs:sequence>
670
+ <xs:element name="Name" type="xs:string"/>
671
+ <xs:element name="Comment" type="xs:string"/>
672
+ </xs:sequence>
673
+ </xs:complexType>
674
+
675
+ <xs:element name="QAGetPromptSet">
676
+ <xs:annotation>
677
+ <xs:documentation>QAGetPromptSet defines a request for details of a prompt set</xs:documentation>
678
+ <xs:documentation>Child elements are as follows:</xs:documentation>
679
+ <xs:documentation>Country : The country dataset</xs:documentation>
680
+ <xs:documentation>PromptSet : The prompt set to get details of</xs:documentation>
681
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
682
+ </xs:annotation>
683
+ <xs:complexType>
684
+ <xs:sequence>
685
+ <xs:element name="Country" type="qas:DataIDType"/>
686
+ <xs:element name="Engine" type="qas:EngineType" minOccurs="0"/>
687
+ <xs:element name="PromptSet" type="qas:PromptSetType"/>
688
+ </xs:sequence>
689
+ <xs:attribute name="Localisation" type="xs:string"/>
690
+ </xs:complexType>
691
+ </xs:element>
692
+
693
+ <xs:element name="QAPromptSet">
694
+ <xs:annotation>
695
+ <xs:documentation>QAPromptSet describes a prompt set</xs:documentation>
696
+ <xs:documentation>Child element:</xs:documentation>
697
+ <xs:documentation>Line : Describes one line of the prompt set</xs:documentation>
698
+ </xs:annotation>
699
+ <xs:complexType>
700
+ <xs:sequence>
701
+ <xs:element name="Line" type="qas:PromptLine" minOccurs="0" maxOccurs="unbounded"/>
702
+ </xs:sequence>
703
+ <xs:attribute name="Dynamic" type="xs:boolean" default="false"/>
704
+ </xs:complexType>
705
+ </xs:element>
706
+
707
+ <xs:complexType name="PromptLine">
708
+ <xs:annotation>
709
+ <xs:documentation>PromptLine describes a line of a prompt set</xs:documentation>
710
+ <xs:documentation>Child elements are as follows:</xs:documentation>
711
+ <xs:documentation>Prompt : The prompt to display to the user</xs:documentation>
712
+ <xs:documentation>SuggestedInputLength : The suggested length of the input buffer</xs:documentation>
713
+ <xs:documentation>Example : An example of possible input</xs:documentation>
714
+ </xs:annotation>
715
+ <xs:sequence>
716
+ <xs:element name="Prompt" type="xs:string"/>
717
+ <xs:element name="SuggestedInputLength" type="xs:nonNegativeInteger"/>
718
+ <xs:element name="Example" type="xs:string"/>
719
+ </xs:sequence>
720
+ </xs:complexType>
721
+
722
+ <xs:element name="QACanSearch">
723
+ <xs:annotation>
724
+ <xs:documentation>QACanSearch returns a boolean specifying whether a search is possible for a</xs:documentation>
725
+ <xs:documentation>specific country, engine and layout</xs:documentation>
726
+ <xs:documentation>Child elements are as follows:</xs:documentation>
727
+ <xs:documentation>Country : The country dataset</xs:documentation>
728
+ <xs:documentation>Engine : The search engine to use, and any engine specific configuration settings</xs:documentation>
729
+ <xs:documentation>Layout : The layout with which to format the address</xs:documentation>
730
+ <xs:documentation>Localisation : Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
731
+ <xs:documentation/>
732
+ </xs:annotation>
733
+ <xs:complexType>
734
+ <xs:sequence>
735
+ <xs:element name="Country" type="qas:DataIDType"/>
736
+ <xs:element name="Engine" type="qas:EngineType"/>
737
+ <xs:element name="Layout" type="xs:string" minOccurs="0"/>
738
+ </xs:sequence>
739
+ <xs:attribute name="Localisation" type="xs:string"/>
740
+ </xs:complexType>
741
+ </xs:element>
742
+
743
+ <xs:element name="QASearchOk">
744
+ <xs:annotation>
745
+ <xs:documentation>QASearchOK is the response from a CanSearch operation.</xs:documentation>
746
+ <xs:documentation>Child elements are as follows:</xs:documentation>
747
+ <xs:documentation>IsOk : Boolean stating whether searching is available</xs:documentation>
748
+ <xs:documentation>ErrorCode : The QAS error code returned</xs:documentation>
749
+ <xs:documentation>ErrorMesage : A textual description of the error</xs:documentation>
750
+ <xs:documentation>ErrorDetail : Detailed error history</xs:documentation>
751
+ </xs:annotation>
752
+ <xs:complexType>
753
+ <xs:sequence>
754
+ <xs:element name="IsOk" type="xs:boolean"/>
755
+ <xs:element name="ErrorCode" type="xs:string" minOccurs="0"/>
756
+ <xs:element name="ErrorMessage" type="xs:string" minOccurs="0"/>
757
+ <xs:element name="ErrorDetail" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
758
+ </xs:sequence>
759
+ </xs:complexType>
760
+ </xs:element>
761
+
762
+ <xs:annotation>
763
+ <xs:documentation> Please refer to the associated Pro On Demand web service documentation for information about this feature.</xs:documentation>
764
+
765
+ </xs:annotation>
766
+
767
+ <xs:complexType name="VerificationFlagsType">
768
+ <xs:sequence>
769
+ <xs:element name="BldgFirmNameChanged" type="xs:boolean" default="false" minOccurs="0"/>
770
+ <xs:element name="PrimaryNumberChanged" type="xs:boolean" default="false" minOccurs="0"/>
771
+ <xs:element name="StreetCorrected" type="xs:boolean" default="false" minOccurs="0"/>
772
+ <xs:element name="RuralRteHighwayContractMatched" type="xs:boolean" default="false" minOccurs="0"/>
773
+ <xs:element name="CityNameChanged" type="xs:boolean" default="false" minOccurs="0"/>
774
+ <xs:element name="CityAliasMatched" type="xs:boolean" default="false" minOccurs="0"/>
775
+ <xs:element name="StateProvinceChanged" type="xs:boolean" default="false" minOccurs="0"/>
776
+ <xs:element name="PostCodeCorrected" type="xs:boolean" default="false" minOccurs="0"/>
777
+ <xs:element name="SecondaryNumRetained" type="xs:boolean" default="false" minOccurs="0"/>
778
+ <xs:element name="IdenPreStInfoRetained" type="xs:boolean" default="false" minOccurs="0"/>
779
+ <xs:element name="GenPreStInfoRetained" type="xs:boolean" default="false" minOccurs="0"/>
780
+ <xs:element name="PostStInfoRetained" type="xs:boolean" default="false" minOccurs="0"/>
781
+ </xs:sequence>
782
+ </xs:complexType>
783
+
784
+ </xs:schema>
785
+ </types>
786
+
787
+ <message name="QueryHeader">
788
+ <part name="query_header" element="qas:QAQueryHeader"/>
789
+ </message>
790
+
791
+ <message name="QAInformation">
792
+ <part name="information_header" element="qas:QAInformation"/>
793
+ </message>
794
+
795
+ <message name="Search">
796
+ <part name="body" element="qas:QASearch"/>
797
+ </message>
798
+
799
+ <message name="SearchResult">
800
+ <part name="body" element="qas:QASearchResult"/>
801
+ </message>
802
+
803
+ <message name="Refine">
804
+ <part name="body" element="qas:QARefine"/>
805
+ </message>
806
+
807
+ <message name="Picklist">
808
+ <part name="body" element="qas:Picklist"/>
809
+ </message>
810
+
811
+ <message name="GetAddress">
812
+ <part name="body" element="qas:QAGetAddress"/>
813
+ </message>
814
+
815
+ <message name="Address">
816
+ <part name="body" element="qas:Address"/>
817
+ </message>
818
+
819
+ <message name="GetData">
820
+ <part name="body" element="qas:QAGetData"/>
821
+ </message>
822
+
823
+ <message name="Data">
824
+ <part name="body" element="qas:QAData"/>
825
+ </message>
826
+
827
+ <message name="GetDataMapDetail">
828
+ <part name="body" element="qas:QAGetDataMapDetail"/>
829
+ </message>
830
+
831
+ <message name="DataMapDetail">
832
+ <part name="body" element="qas:QADataMapDetail"/>
833
+ </message>
834
+
835
+ <message name="GetLicenseInfo">
836
+ <part name="body" element="qas:QAGetLicenseInfo"/>
837
+ </message>
838
+
839
+ <message name="LicenseInfo">
840
+ <part name="body" element="qas:QALicenceInfo"/>
841
+ </message>
842
+
843
+ <message name="GetSystemInfo">
844
+ <part name="body" element="qas:QAGetSystemInfo"/>
845
+ </message>
846
+
847
+ <message name="SystemInfo">
848
+ <part name="body" element="qas:QASystemInfo"/>
849
+ </message>
850
+
851
+ <message name="GetExampleAddresses">
852
+ <part name="body" element="qas:QAGetExampleAddresses"/>
853
+ </message>
854
+
855
+ <message name="ExampleAddresses">
856
+ <part name="body" element="qas:QAExampleAddresses"/>
857
+ </message>
858
+
859
+ <message name="GetLayouts">
860
+ <part name="body" element="qas:QAGetLayouts"/>
861
+ </message>
862
+
863
+ <message name="Layouts">
864
+ <part name="body" element="qas:QALayouts"/>
865
+ </message>
866
+
867
+ <message name="GetPromptSet">
868
+ <part name="body" element="qas:QAGetPromptSet"/>
869
+ </message>
870
+
871
+ <message name="PromptSet">
872
+ <part name="body" element="qas:QAPromptSet"/>
873
+ </message>
874
+
875
+ <message name="CanSearch">
876
+ <part name="body" element="qas:QACanSearch"/>
877
+ </message>
878
+
879
+ <message name="SearchOk">
880
+ <part name="body" element="qas:QASearchOk"/>
881
+ </message>
882
+
883
+ <portType name="QAPortType">
884
+ <operation name="DoSearch">
885
+ <input message="qas:Search"/>
886
+ <output message="qas:SearchResult"/>
887
+ </operation>
888
+
889
+ <operation name="DoRefine">
890
+ <input message="qas:Refine"/>
891
+ <output message="qas:Picklist"/>
892
+ </operation>
893
+
894
+ <operation name="DoGetAddress">
895
+ <input message="qas:GetAddress"/>
896
+ <output message="qas:Address"/>
897
+ </operation>
898
+
899
+ <operation name="DoGetData">
900
+ <input message="qas:GetData"/>
901
+ <output message="qas:Data"/>
902
+ </operation>
903
+
904
+ <operation name="DoGetDataMapDetail">
905
+ <input message="qas:GetDataMapDetail"/>
906
+ <output message="qas:DataMapDetail"/>
907
+ </operation>
908
+
909
+ <operation name="DoGetLicenseInfo">
910
+ <input message="qas:GetLicenseInfo"/>
911
+ <output message="qas:LicenseInfo"/>
912
+ </operation>
913
+
914
+ <operation name="DoGetSystemInfo">
915
+ <input message="qas:GetSystemInfo"/>
916
+ <output message="qas:SystemInfo"/>
917
+ </operation>
918
+
919
+ <operation name="DoGetExampleAddresses">
920
+ <input message="qas:GetExampleAddresses"/>
921
+ <output message="qas:ExampleAddresses"/>
922
+ </operation>
923
+
924
+ <operation name="DoGetLayouts">
925
+ <input message="qas:GetLayouts"/>
926
+ <output message="qas:Layouts"/>
927
+ </operation>
928
+
929
+ <operation name="DoGetPromptSet">
930
+ <input message="qas:GetPromptSet"/>
931
+ <output message="qas:PromptSet"/>
932
+ </operation>
933
+
934
+ <operation name="DoCanSearch">
935
+ <input message="qas:CanSearch"/>
936
+ <output message="qas:SearchOk"/>
937
+ </operation>
938
+ </portType>
939
+
940
+ <binding name="QASOnDemand" type="qas:QAPortType">
941
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
942
+
943
+ <operation name="DoSearch">
944
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoSearch"/>
945
+ <input>
946
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
947
+ <soap:body use="literal"/>
948
+ </input>
949
+ <output>
950
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
951
+ <soap:body use="literal"/>
952
+ </output>
953
+ </operation>
954
+
955
+ <operation name="DoRefine">
956
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoRefine"/>
957
+ <input>
958
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
959
+ <soap:body use="literal"/>
960
+ </input>
961
+ <output>
962
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
963
+ <soap:body use="literal"/>
964
+ </output>
965
+ </operation>
966
+
967
+ <operation name="DoGetAddress">
968
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetAddress"/>
969
+ <input>
970
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
971
+ <soap:body use="literal"/>
972
+ </input>
973
+ <output>
974
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
975
+ <soap:body use="literal"/>
976
+ </output>
977
+ </operation>
978
+
979
+ <operation name="DoGetData">
980
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetData"/>
981
+ <input>
982
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
983
+ <soap:body use="literal"/>
984
+ </input>
985
+ <output>
986
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
987
+ <soap:body use="literal"/>
988
+ </output>
989
+ </operation>
990
+
991
+ <operation name="DoGetDataMapDetail">
992
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetDataMapDetail"/>
993
+ <input>
994
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
995
+ <soap:body use="literal"/>
996
+ </input>
997
+ <output>
998
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
999
+ <soap:body use="literal"/>
1000
+ </output>
1001
+ </operation>
1002
+
1003
+ <operation name="DoGetLicenseInfo">
1004
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetLicenseInfo"/>
1005
+ <input>
1006
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1007
+ <soap:body use="literal"/>
1008
+ </input>
1009
+ <output>
1010
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1011
+ <soap:body use="literal"/>
1012
+ </output>
1013
+ </operation>
1014
+
1015
+ <operation name="DoGetSystemInfo">
1016
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetSystemInfo"/>
1017
+ <input>
1018
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1019
+ <soap:body use="literal"/>
1020
+ </input>
1021
+ <output>
1022
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1023
+ <soap:body use="literal"/>
1024
+ </output>
1025
+ </operation>
1026
+
1027
+ <operation name="DoGetExampleAddresses">
1028
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetExampleAddresses"/>
1029
+ <input>
1030
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1031
+ <soap:body use="literal"/>
1032
+ </input>
1033
+ <output>
1034
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1035
+ <soap:body use="literal"/>
1036
+ </output>
1037
+ </operation>
1038
+
1039
+ <operation name="DoGetLayouts">
1040
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetLayouts"/>
1041
+ <input>
1042
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1043
+ <soap:body use="literal"/>
1044
+ </input>
1045
+ <output>
1046
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1047
+ <soap:body use="literal"/>
1048
+ </output>
1049
+ </operation>
1050
+
1051
+ <operation name="DoGetPromptSet">
1052
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoGetPromptSet"/>
1053
+ <input>
1054
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1055
+ <soap:body use="literal"/>
1056
+ </input>
1057
+ <output>
1058
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1059
+ <soap:body use="literal"/>
1060
+ </output>
1061
+ </operation>
1062
+
1063
+ <operation name="DoCanSearch">
1064
+ <soap:operation soapAction="http://www.qas.com/OnDemand-2011-03/DoCanSearch"/>
1065
+ <input>
1066
+ <soap:header message="qas:QueryHeader" part="query_header" use="literal"/>
1067
+ <soap:body use="literal"/>
1068
+ </input>
1069
+ <output>
1070
+ <soap:header message="qas:QAInformation" part="information_header" use="literal"/>
1071
+ <soap:body use="literal"/>
1072
+ </output>
1073
+ </operation>
1074
+ </binding>
1075
+
1076
+ <service name="QASOnDemandIntermediary">
1077
+ <port binding="qas:QASOnDemand" name="QAPortType">
1078
+ <soap:address location="https://ws.ondemand.qas.com/ProOnDemand/V3/ProOnDemandService.asmx"/>
1079
+ </port>
1080
+ </service>
1081
+ </definitions>
lib/ExperianDataQuality/PromptSetType.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PromptSetType
3
+ {
4
+ //const \DEFAULT = 'Default';
5
+ const ONELINE = 'OneLine';
6
+ const GENERIC = 'Generic';
7
+ const OPTIMAL = 'Optimal';
8
+ const ALTERNATE = 'Alternate';
9
+ const ALTERNATE2 = 'Alternate2';
10
+ const ALTERNATE3 = 'Alternate3';
11
+ }
lib/ExperianDataQuality/QAAddress.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'AddressLine.php';
3
+ include_once 'DPVStatusType.php';
4
+
5
+ class QAAddress
6
+ {
7
+ public $AddressLine = array();
8
+ public $Overflow;
9
+ public $Truncated;
10
+ public $DPVStatus;
11
+ public $DPVStatusSpecified;
12
+ public $MissingSubPremise;
13
+
14
+ public function __construct($response)
15
+ {
16
+ if(isset($response->AddressLine) === \FALSE)
17
+ {
18
+ $this->AddressLine = array();
19
+ }
20
+ else
21
+ {
22
+ if(is_array($response->AddressLine))
23
+ {
24
+ foreach ($response->AddressLine as $value)
25
+ {
26
+ \array_push($this->AddressLine, new AddressLine($value));
27
+ }
28
+ }
29
+ else
30
+ {
31
+ \array_push($this->AddressLine, new AddressLine($response->AddressLine));
32
+ }
33
+ }
34
+
35
+ $this->Overflow = \FALSE;
36
+ $this->Truncated = \FALSE;
37
+ $this->DPVStatus = isset($response->DPVStatus) ? $response->DPVStatus : \FALSE;
38
+ $this->DPVStatusSpecified = isset($response->DPVStatusSpecified) ? $response->DPVStatusSpecified : DPVStatusType::DPVNOTCONFIRMED;
39
+ $this->MissingSubPremise = isset($response->MissingSubPremise) ? $response->MissingSubPremise : \FALSE;
40
+ }
41
+ }
lib/ExperianDataQuality/QAAuthentication.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QAAuthentication
3
+ {
4
+ private $Username;
5
+ private $Password;
6
+
7
+ public function __construct($username,$password)
8
+ {
9
+ $this->Username = $username;
10
+ $this->Password = $password;
11
+ }
12
+ }
lib/ExperianDataQuality/QACanSearch.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QACanSearch
3
+ {
4
+ private $Country;
5
+ private $Engine;
6
+ private $Layout;
7
+ private $Localisation;
8
+
9
+ public function __construct($countryField, $engineField, $layoutField, $localisationField = \NULL)
10
+ {
11
+ $this->Country = $countryField;
12
+ $this->Engine = $engineField;
13
+ $this->Layout = $layoutField;
14
+ $this->Localisation = $localisationField;
15
+ }
16
+ }
lib/ExperianDataQuality/QAGetAddress.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QAGetAddress
3
+ {
4
+ private $Layout;
5
+ private $Moniker;
6
+ private $Localisation = \FALSE;
7
+
8
+ public function __construct($layoutField, $monikerField)
9
+ {
10
+ $this->Layout = $layoutField;
11
+ $this->Moniker = $monikerField;
12
+ }
13
+ }
lib/ExperianDataQuality/QAGetLayouts.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QAGetLayouts
3
+ {
4
+ private $Country;
5
+
6
+ public function __construct($country)
7
+ {
8
+ $this->Country = $country;
9
+ }
10
+ }
lib/ExperianDataQuality/QALayouts.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'Layout.php';
3
+
4
+ class QALayouts
5
+ {
6
+ public $Layout = array();
7
+
8
+ public function __construct($response)
9
+ {
10
+ if(isset($response->Layout) === \FALSE)
11
+ {
12
+ $this->Layout = array();
13
+ }
14
+ else
15
+ {
16
+ if(is_array($response->Layout))
17
+ {
18
+ foreach ($response->Layout as $layout)
19
+ {
20
+ \array_push($this->Layout, new Layout($layout->Name, $layout->Comment));
21
+ }
22
+ }
23
+ else
24
+ {
25
+ \array_push($this->Layout, new Layout($layout->Name, $layout->Comment));
26
+ }
27
+ }
28
+ }
29
+ }
lib/ExperianDataQuality/QAPicklist.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'Picklist.php';
3
+ include_once 'PicklistEntry.php';
4
+
5
+ class QAPicklist
6
+ {
7
+ public $FullPicklistMoniker;
8
+ public $PicklistEntry = array();
9
+ public $Prompt;
10
+ public $Total;
11
+ public $AutoFormatSafe = \FALSE;
12
+ public $AutoFormatPastClose = \FALSE;
13
+ public $AutoStepinSafe = \FALSE;
14
+ public $AutoStepinPastClose = \FALSE;
15
+ public $LargePotential = \FALSE;
16
+ public $MaxMatches = \FALSE;
17
+ public $MoreOtherMatches = \FALSE;
18
+ public $OverThreshold = \FALSE;
19
+ public $Timeout = \FALSE;
20
+
21
+ public function __construct($response)
22
+ {
23
+ if(isset($response->PicklistEntry) === \FALSE)
24
+ {
25
+ $this->PicklistEntry = array();
26
+ }
27
+ else
28
+ {
29
+ if(is_array($response->PicklistEntry))
30
+ {
31
+ foreach ($response->PicklistEntry as $value)
32
+ {
33
+ \array_push($this->PicklistEntry, new PicklistEntry($value));
34
+ }
35
+ }
36
+ else
37
+ {
38
+ \array_push($this->PicklistEntry, new PicklistEntry($response->PicklistEntry));
39
+ }
40
+ }
41
+ $this->FullPicklistMoniker = isset($response->FullPicklistMoniker) ? $response->FullPicklistMoniker : \FALSE;
42
+ $this->Prompt = isset($response->Prompt) ? $response->Prompt : \FALSE;
43
+ $this->Total = isset($response->Total) ? $response->Total : \FALSE;
44
+ }
45
+ }
lib/ExperianDataQuality/QAQueryHeader.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'QAAuthentication.php';
3
+
4
+ class QAQueryHeader
5
+ {
6
+ private $QAAuthentication;
7
+ private $Security;
8
+
9
+ public function __construct($username,$password)
10
+ {
11
+ $this->QAAuthentication = new QAAuthentication($username, $password);
12
+ $this->Security = \NULL;
13
+ }
14
+ }
lib/ExperianDataQuality/QARefine.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QARefine
3
+ {
4
+ private $Moniker;
5
+ private $Refinement;
6
+ private $Layout;
7
+ private $Threshold;
8
+ private $Timeout;
9
+ private $Localisation = \FALSE;
10
+ private $FormattedAddressInPicklist = \FALSE;
11
+
12
+ public function __construct($monikerField, $refinementField, $layoutField, $thresholdField, $timeoutField)
13
+ {
14
+ $this->Moniker = $monikerField;
15
+ $this->Refinement = $refinementField;
16
+ $this->Layout = $layoutField;
17
+ $this->Threshold = $thresholdField;
18
+ $this->Timeout = $timeoutField;
19
+ }
20
+ }
lib/ExperianDataQuality/QASearch.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QASearch
3
+ {
4
+ private $Country;
5
+ private $Engine;
6
+ private $Layout;
7
+ private $Search;
8
+ private $FormattedAddressInPicklist;
9
+ private $Localisation;
10
+
11
+ public function __construct($countryField, $engineField, $layoutField, $searchField, $localisationField = \NULL)
12
+ {
13
+ $this->Country = $countryField;
14
+ $this->Engine = $engineField;
15
+ $this->Layout = $layoutField;
16
+ $this->Search = $searchField;
17
+
18
+ if(isset($localisationField))
19
+ {
20
+ $this->Localisation = $localisationField;
21
+ }
22
+
23
+ $this->FormattedAddressInPicklist = \FALSE;
24
+ }
25
+ }
lib/ExperianDataQuality/QASearchOk.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class QASearchOk
3
+ {
4
+ public $IsOk;
5
+ public $ErrorCode;
6
+ public $ErrorMessage;
7
+ public $ErrorDetail;
8
+
9
+ public function __construct($response)
10
+ {
11
+ $this->IsOk = isset($response->IsOk) ? $response->IsOk : \FALSE;
12
+ $this->ErrorCode = isset($response->ErrorCode) ? $response->ErrorCode : \FALSE;
13
+ $this->ErrorMessage = isset($response->ErrorMessage) ? $response->ErrorMessage : \FALSE;
14
+ $this->ErrorDetail = isset($response->ErrorDetail) ? $response->ErrorDetail : \FALSE;
15
+ }
16
+ }
lib/ExperianDataQuality/QASearchResult.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once 'QAPicklist.php';
3
+ include_once 'VerifyLevelType.php';
4
+
5
+ class QASearchResult
6
+ {
7
+ public $QAPicklist;
8
+ public $QAAddress;
9
+ public $VerificationFlags;
10
+ public $VerificationFlagsType;
11
+
12
+ public function __construct($response)
13
+ {
14
+ $this->QAPicklist = isset($response->QAPicklist) ? new QAPicklist($response->QAPicklist) : FALSE;
15
+ $this->QAAddress = isset($response->QAAddress) ? $response->QAAddress : FALSE;
16
+ $this->VerificationFlags = isset($response->VerificationFlags) ? $response->VerificationFlags : FALSE;
17
+ $this->VerificationFlagsType = isset($response->VerifyLevel) ? $response->VerifyLevel : VerifyLevelType::NONE;
18
+ }
19
+ }
lib/ExperianDataQuality/ServiceFactory.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/GlobalSettings.php';
3
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/Common/HelperMethods.php';
4
+ include_once Mage::getBaseDir('lib') . '/ExperianDataQuality/ProOnDemandService.php';
5
+
6
+ class ExperianDataQuality_ServiceFactory
7
+ {
8
+ public static function createService($serviceType = NULL, $token = NULL)
9
+ {
10
+ $service = \NULL;
11
+
12
+ if(HelperMethods::isNullOrWhiteSpace($serviceType))
13
+ {
14
+ $serviceType = GlobalSettings::instance()->getServiceProvide();
15
+ }
16
+
17
+ switch ($serviceType)
18
+ {
19
+ case 'proondemand':
20
+ $service = new ExperianDataQuality_ProOnDemandService($token);
21
+ break;
22
+ default:
23
+ $message = "Service type " . $serviceType . " is not supported.";
24
+ throw new \Exception($message);
25
+ }
26
+
27
+ return $service;
28
+ }
29
+ }
lib/ExperianDataQuality/VerifyLevelType.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class VerifyLevelType
3
+ {
4
+ const NONE = 'None';
5
+ const VERIFIED = 'Verified';
6
+ const INTERACTIONREQUIRED = 'InteractionRequired';
7
+ const PREMISSESPARTIAL = 'PremisesPartial';
8
+ const STREETPARTIAL = 'StreetPartial';
9
+ const MULTIPLE = 'Multiple';
10
+ const VERIFIEDPLACE = 'VerifiedPlace';
11
+ const VERIFIEDSTREET = 'VerifiedStreet';
12
+ }
package.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Experian_Data_Quality_Validation_Services</name>
4
+ <version>1.0.0.0</version>
5
+ <stability>stable</stability>
6
+ <license>GNU General Public License (GPL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Address, email, and phone verification services for Magento Enterprise and Community editions.</summary>
10
+ <description>Experian Data Quality's tools for address, email, and phone verification provide a seamless integration with the Magento platform while delivering quality results for your eCommerce store.</description>
11
+ <notes>Address verification for both front and back-end touch points, with support for addresses in the USA, CAN, GBR, IRE, and DEU.&#xD;
12
+ &#xD;
13
+ Email and phone verification services provide real-time verification at the point of entry.&#xD;
14
+ &#xD;
15
+ This extension is a bundle containing Experian Data Quality's address and email/phone products in a single extension. Separate license keys may be necessary for each service. Contact your Experian Data Quality sales representative for more information.</notes>
16
+ <authors><author><name>David Morton</name><user>DavidMorton</user><email>David.Morton@experian.com</email></author><author><name>ExperianDataQualityValidationServices</name><user>ExperianDataQualityValidationServices</user><email>internetmarketing@qas.com</email></author></authors>
17
+ <date>2017-01-30</date>
18
+ <time>19:40:44</time>
19
+ <contents><target name="magecommunity"><dir name="EDQ"><dir name="AddressValidation"><dir name="Helper"><file name="Data.php" hash="cc5a0e37c5b31e72be7d1f7bfa36de7c"/><file name="Methods.php" hash="d654049f1d58b48970d69eaf3637d069"/><file name="Settings.php" hash="4aefab7315311f3039c2146d3d4b1e1a"/></dir><dir name="Model"><file name="Customer.php" hash="58eca6bee0c7b2c2cb91ef358f616829"/><file name="DataCenters.php" hash="69a930f8d107c407b224b1a28c318382"/><file name="DoCanSearchParameters.php" hash="0704ecc29ad618b3bccc387f20e3028d"/><file name="Observer.php" hash="f1e4b200bb21627d1db725d65e5ea552"/><file name="Quote.php" hash="eeba356453074add94438a3b5e0da6e9"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="278c873dfd78ed79ba43ae31caa9260a"/></dir><file name="Customer.php" hash="f3e335be0f8cfb716a6ebada95138733"/><dir name="Quote"><file name="Collection.php" hash="18783fe3df00710cb00b4967c722e0df"/></dir><file name="Quote.php" hash="fab9ce2a1643d6d0a75622c6d1dc8411"/></dir><file name="Service.php" hash="061c0a3744542751aebcc76b58cc9953"/><file name="ServiceProviders.php" hash="452daf1b13be7e46d7178f52193174e2"/><file name="Validate.php" hash="a76d8bee1272f466c6bab149a80cae69"/></dir><dir name="controllers"><file name="ProcessAdminController.php" hash="44252efca489f7b848f88d18e79ba209"/><file name="ProcessController.php" hash="f4af29f11a1cc23c8073367eaf5f1e18"/></dir><dir name="etc"><file name="adminhtml.xml" hash="8e8b3d45b502a37a7ff2ffd00b3f69a5"/><file name="config.xml" hash="ffaf14b06a26a88ee988ab0f20f3bc7f"/><file name="system.xml" hash="291dda35bc27359e132452026b5849de"/></dir><dir name="sql"><dir name="addressvalidation_setup"><file name="install-1.0.5.php" hash="b1ea1c4c75fd45501abb60fb1c0d395d"/></dir></dir></dir><dir name="EmailAndPhoneValidation"><dir name="Helper"><file name="Data.php" hash="7a87484dab745f067c053b3c3c0dc063"/></dir><dir name="Model"><file name="Observer.php" hash="c1fabe198f5e7f2aa546998871683dcf"/><dir name="Phone"><file name="PhoneFormater.php" hash="aeaa1fac4250df1d2c2bf8afc52d4543"/></dir><file name="SupportedCountries.php" hash="96766bb53bd60704a4fb469b0b082aac"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Countries.php" hash="88a7f0691b165a4162520d0f6fb6a5fe"/></dir></dir></dir><file name="Validate.php" hash="a1f096655394230e7fc2ec5ec1d7da86"/></dir><dir name="controllers"><file name="ValidationController.php" hash="9d242d304548309d48867b2bff9ced68"/></dir><dir name="etc"><file name="adminhtml.xml" hash="7d3be3be34edf837e1f83574c54e82a4"/><file name="config.xml" hash="b7f83dce7f38bc1841a82335c97633e5"/><file name="system.xml" hash="76ce8a49c29e71b5daf557160e8c7faa"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="edqaddressvalidation.xml" hash="049d54a05d2d5b7e6e4d0cb4fee78b40"/><file name="edqemailandphonevalidation.xml" hash="023eb0d486279d3a09611455ccf214a9"/></dir><dir name="template"><dir name="edq"><file name="singleline.phtml" hash="b5b4ccfacdf70166d0111dbe546de813"/><file name="verify.phtml" hash="eddbe0d0805dae0010d90d6bf54fb202"/><file name="initialize.phtml" hash="90a160b2918498dae443936449aa4603"/></dir><file name="securityToken.phtml" hash=""/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="edqaddressvalidation.xml" hash="db40341caa965625ca4f268d3cb2f882"/><file name="edqemailandphonevalidation.xml" hash="12f780547673d92817d515a0fb18b269"/></dir><dir name="template"><dir name="edq"><dir name="checkout"><file name="verify.phtml" hash="04f5f92d3080efd7e7c008cefc1e9139"/><file name="configurations.phtml" hash="3fa483dc71219daf518f2784e2bd063f"/></dir><dir name="customer"><file name="verify.phtml" hash="f6d01c8bf21f5ee086840026225d8752"/><dir name="address"><file name="phoneConfigurations.phtml" hash="4981e6f6f52f28bcbcc4a73459be99d3"/></dir><dir name="form"><file name="emailConfigurations.phtml" hash="65f40991fef1ac15f5db97d0585b7a07"/></dir></dir><file name="interaction.phtml" hash="97647331de1833bd8969c7e469eee4f0"/><file name="popup.phtml" hash="be66ab141cf3b5715a7bd0fc649c5c0f"/><file name="rightside.phtml" hash="81caa36bfe9fb2954e4879b38839e526"/><file name="singleline.phtml" hash="029218b530269750104d3d2c372cd8ba"/><file name="initialize.phtml" hash="1fa4e93bd3279598881bc9f69cca43ae"/><file name="securityToken.phtml" hash="db07b76573368bb9f7c72969f3287883"/></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="ExperianDataQuality"><file name="Address.php" hash="36e3a6ebe3f55469a279777750827f83"/><file name="AddressLine.php" hash="b9b69906269259251ea764e804d82178"/><file name="AddressValidationParser.php" hash="96069cf576594f8ff3e28e81000ed264"/><file name="AddressValidationReference.php" hash="b3fcc3796994694d7cc6f9aa70812cb7"/><file name="BaseService.php" hash="6c6f0a5443e02d8a990fa75d5b5d2eb1"/><dir name="Common"><file name="GlobalSettings.php" hash="40b9bdd9184ceb3aaadb58f1addd2c90"/><file name="HelperMethods.php" hash="1ccbac84af091e4ac3adfe7bd9fff749"/><dir name="Request"><file name="BaseAddressRequest.php" hash="2b606849afdf3313d1fa6a6bd5db2c90"/><file name="BaseSearchRequest.php" hash="7fe2964ebb111ddcdd3a299ef485eb80"/><file name="CanSearchRequest.php" hash="cfe030083b29695c1f62f6dc424bfdd9"/><file name="GetAddressRequest.php" hash="6eb25de64b0c4fa99ed624416c86a1a9"/><file name="GetLayoutsRequest.php" hash="be2c2cdde6851d58a09dbed10e96d2dc"/><file name="RefineRequest.php" hash="874e2384cd8c19583d39814d24a1eb18"/><file name="SearchRequest.php" hash="8f1ea1be702313ad2f2a7e3d81359e0d"/></dir><dir name="Response"><file name="BaseSearchResponse.php" hash="68a834820e00ffdad127b07acf901541"/><file name="CanSearchResponse.php" hash="975b7b8548f93c32da79c62755a54608"/><file name="GetAddressResponse.php" hash="a6b8f8a9e37a04847f39951da20b77ec"/><file name="GetLayoutResponse.php" hash="05bdb7c9958e0cca73cc0723c1e592a5"/><file name="RefineResponse.php" hash="fd505eafcd459d607e2a9e32996d85d5"/><file name="SearchResponse.php" hash="a1eb49afff2c73b9120fca7ffd9b047e"/></dir></dir><file name="DPVStatusType.php" hash="968cfef0f7f627b8fe8f9e2f1385d297"/><file name="EngineEnumType.php" hash="c46da44618b8a20f713e545da9930b3d"/><file name="EngineType.php" hash="38ad2422487361de2a7eba1be754392c"/><file name="IService.php" hash="655ec70b7d0911363e556362ec639e91"/><file name="Layout.php" hash="569a50dd2895f87e4c3d35a436dc5fde"/><file name="LineContentType.php" hash="0049722932a88450f53564fd8170b324"/><file name="Picklist.php" hash="a0ba1ba2a85e08895e5a1430c007fab0"/><file name="PicklistEntry.php" hash="71617ff5d7a3ae90181ae8eb68a0c81f"/><file name="ProOnDemandService.php" hash="7daca0de8c92edabf950043d123ca0eb"/><file name="ProOnDemandService.wsdl" hash="a654d96ffc6c84ff8494f3c752e674d4"/><file name="PromptSetType.php" hash="54ff4a3253b9ab4ba63219c4cd565878"/><file name="QAAddress.php" hash="16059de94089d9feb62d03f495ab4a29"/><file name="QAAuthentication.php" hash="b2a629efbac6403471e6fc8f9c5e3683"/><file name="QACanSearch.php" hash="e89bcc849bfa62bbbe0116ae7131057d"/><file name="QAGetAddress.php" hash="354da3ff6691bb1c166874df7735e5ef"/><file name="QAGetLayouts.php" hash="bedaed731213421e94874ef498a5e7d9"/><file name="QALayouts.php" hash="5411b663e68f381a32af96dfc345202a"/><file name="QAPicklist.php" hash="c5e39ca62aa54be2c051397dc64f1ed4"/><file name="QAQueryHeader.php" hash="54fa7549afc3014c411ba05105320f92"/><file name="QARefine.php" hash="e08255fe0abdf27f30799729d36a4079"/><file name="QASearch.php" hash="9da9ba2339f7bd94159f0cc9a115c403"/><file name="QASearchOk.php" hash="72c86e5a16878dadad50c33a620faaed"/><file name="QASearchResult.php" hash="c7d171b85665744384f6190eb59b68df"/><file name="ServiceFactory.php" hash="f1ef07a056c2d4dbe4c1b9cb88747829"/><file name="VerifyLevelType.php" hash="0a2731af83eb39884367879a54f2250b"/></dir><dir name="EDQ"><file name="WshEmailValidator.php" hash="59c4c64bc285def668156147d945c205"/><file name="WshPhoneValidator.php" hash="3d165c269970d5f6a953ea42c6c1aea4"/><file name="WshValidator.php" hash="6a1a3c839387f5ad162f4cbb044d6b14"/><file name="WshValidatorFactory.php" hash="75a7c497a8ca03b9e78b0da8be4bad40"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="ExperianDataQuality"><dir name="images"><file name="opc-ajax-loader.gif" hash="7b9776076d5fceef4993b55c9383dedd"/></dir><dir name="js"><file name="edqAddressClient.js" hash="2516da1a45c4e87a0b903bb640a3f494"/><file name="edqClient.js" hash="02fe86abf39028a72255b663b37c270e"/><file name="json2.js" hash="74d903049683e5bbea9ccb7544a42bca"/><file name="system.js" hash="81d4b19c630c6aa43954877029a038d2"/></dir></dir><dir name="edq"><dir name="images"><file name="opc-ajax-loader.gif" hash="e805ea7eca1f34c75ba0f93780d32d38"/></dir><dir name="js"><file name="edqClient.js" hash="df5a3be439a84340cfd9f9d7f454349a"/><file name="json2.js" hash="74d903049683e5bbea9ccb7544a42bca"/><file name="system.js" hash="7500bee2c32e6d4806ee46ae75b458c5"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="ExperianDataQuality"><dir name="images"><file name="opc-ajax-loader.gif" hash="7b9776076d5fceef4993b55c9383dedd"/></dir><dir name="js"><file name="edqAddressClient.js" hash="8b0e3aad9810e50499b6cb88bdb5f374"/><file name="edqClient.js" hash="9752f5987390ea07793b442d24019550"/><file name="json2.js" hash="74d903049683e5bbea9ccb7544a42bca"/><file name="system.js" hash="81d4b19c630c6aa43954877029a038d2"/></dir></dir><dir name="edq"><dir name="images"><file name="opc-ajax-loader.gif" hash="e805ea7eca1f34c75ba0f93780d32d38"/></dir><dir name="js"><file name="edqClient.js" hash="df5a3be439a84340cfd9f9d7f454349a"/><file name="json2.js" hash="74d903049683e5bbea9ccb7544a42bca"/><file name="system.js" hash="7500bee2c32e6d4806ee46ae75b458c5"/></dir></dir></dir></dir></dir></target></contents>
20
+ <compatible/>
21
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
22
+ </package>
skin/adminhtml/default/default/ExperianDataQuality/images/opc-ajax-loader.gif ADDED
Binary file
skin/adminhtml/default/default/ExperianDataQuality/js/edqAddressClient.js ADDED
@@ -0,0 +1,672 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ExperianDataQuality.DataQuality.Address = ExperianDataQuality.DataQuality.Address || {};
2
+
3
+ ExperianDataQuality.DataQuality.Address.Configuration = function Configuration(inputMappings, outputMappings) {
4
+ var dq = ExperianDataQuality.DataQuality;
5
+
6
+ this._stage = dq.WorkFlowStages.Input;
7
+
8
+ dq.Configuration.apply(this, [inputMappings, outputMappings, dq.ConfigurationType.Address]);
9
+ };
10
+ ExperianDataQuality.system.inherit(ExperianDataQuality.DataQuality.Address.Configuration, ExperianDataQuality.DataQuality.Configuration);
11
+ ExperianDataQuality.DataQuality.Address.Configuration.SearchServiceUrl = '';
12
+ ExperianDataQuality.DataQuality.Address.Configuration.RefineServiceUrl = '';
13
+ ExperianDataQuality.DataQuality.Address.Configuration.GetAddressServiceUrl = '';
14
+ ExperianDataQuality.DataQuality.Address.Configuration.IsManualEntryAllowed = true;
15
+
16
+ ExperianDataQuality.DataQuality.Address.Client = function Client(configurations) {
17
+ var dq = ExperianDataQuality.DataQuality;
18
+
19
+ dq.Client.apply(this, [configurations]);
20
+ };
21
+ ExperianDataQuality.system.inherit(ExperianDataQuality.DataQuality.Address.Client, ExperianDataQuality.DataQuality.Client);
22
+
23
+ ExperianDataQuality.DataQuality.Address.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) {
24
+ var sys = ExperianDataQuality.system;
25
+ var dq = ExperianDataQuality.DataQuality;
26
+
27
+ var client = this;
28
+
29
+ var dataSetElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.DataSet);
30
+ if (sys.isNull(dataSetElement)) {
31
+ return;
32
+ }
33
+
34
+ var previousOnChange = dataSetElement.onchange;
35
+ dataSetElement.onchange = function (event, value) {
36
+ dq.ManualEntryState = dq.Deactive;
37
+ if (sys.isFunction(previousOnChange)) {
38
+ previousOnChange.apply(this, [event]);
39
+ };
40
+ if(sys.containsInArray(dataSetElement.value, dq.Address.LicensedDataSets) && client._isExistingAddressEdited(configuration) === false) {
41
+ client._showVerifiedAddressPromptSet(configuration, false, dataSetElement.value);
42
+ }
43
+ else {
44
+ client._showPromptSetFor(configuration, this.value);
45
+ }
46
+ };
47
+ dataSetElement.onchange();
48
+
49
+ var chagenAddressElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.ChangeAddressButton);
50
+ chagenAddressElement.onclick = function () { dq.ManualEntryState = dq.Deactive; client._showPromptSetFor(configuration, dataSetElement.value); };
51
+
52
+ var findAddressElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.FindAddressButton);
53
+ findAddressElement.onclick = function () { client._findAddress(configuration); };
54
+
55
+ var manualEntryElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.ManualEntry);
56
+ if(!sys.isNull(manualEntryElement)) {
57
+ manualEntryElement.onclick = function () { client._showPromptSetFor(configuration); dq.ManualEntryState = dq.Active; };
58
+ }
59
+
60
+ var knownPostCodeElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.KnownPostCode);
61
+ knownPostCodeElement.onclick = function () { client._showPromptSetFor(configuration, dataSetElement.value); };
62
+
63
+ var unknownPostCodeElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.UnknownPostCode);
64
+ unknownPostCodeElement.onclick = function () { client._showUnknownPostcodePromptSet(configuration, dataSetElement.value); };
65
+
66
+ var selectSuggestionButtonElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.SelectButton);
67
+ selectSuggestionButtonElement.onclick = function () { client._selectAddress(dataSetElement.value, configuration); };
68
+
69
+ var suggestionsElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
70
+ suggestionsElement.ondblclick = function (event) { client._selectAddress(dataSetElement.value, configuration); };
71
+
72
+ var refineElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.RefineInput);
73
+
74
+ var tryAgainElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.TryAgain);
75
+ tryAgainElement.onclick = function () {
76
+ switch (configuration.stage) {
77
+ case dq.WorkFlowStages.Suggestions:
78
+ client._restoreInputValues(configuration._inputMappings);
79
+ client._selectAddress(dataSetElement.value, configuration);
80
+ break;
81
+ case dq.WorkFlowStages.Refining:
82
+ client._restoreInputValues(configuration._inputMappings);
83
+ client._refineAddress(dataSetElement.value, refineElement.value, configuration);
84
+ break;
85
+ default:
86
+ client._restoreInputValues(configuration._inputMappings);
87
+ client._findAddress(configuration);
88
+ break;
89
+ }
90
+ };
91
+
92
+ var backButtonElements = configuration._getHtmlElementsFromInputMappingByEdqFieldName(dq.BackButton);
93
+
94
+ var backButtonElementOnClick = function () {
95
+ switch (configuration.stage) {
96
+ case dq.WorkFlowStages.Verified:
97
+ if (suggestionsElement.options.length <= 1) {
98
+ client._showPromptSetFor(configuration, dataSetElement.value);
99
+ client._restoreInputValues(configuration._inputMappings);
100
+ break;
101
+ }
102
+ client._showSuggestionsProptset(configuration);
103
+ break;
104
+ case dq.WorkFlowStages.Refining:
105
+ if (suggestionsElement.options.length <= 1) {
106
+ client._showPromptSetFor(configuration, dataSetElement.value);
107
+ client._restoreInputValues(configuration._inputMappings);
108
+ } else {
109
+ client._showSuggestionsProptset(configuration);
110
+ }
111
+ break;
112
+ case dq.WorkFlowStages.Suggestions:
113
+ dq.Address.Client.clearSuggestionList(suggestionsElement);
114
+ client._showPromptSetFor(configuration, dataSetElement.value);
115
+ client._restoreInputValues(configuration._inputMappings);
116
+ break;
117
+ default:
118
+ client._showPromptSetFor(configuration, dataSetElement.value);
119
+ client._restoreInputValues(configuration._inputMappings);
120
+ break;
121
+ }
122
+ client._handleErrorMessage(configuration, dq.ErrorMessage);
123
+ };
124
+
125
+ for(var i = 0, max = backButtonElements.length; i < max; i++) {
126
+ var backButtonHtmlElement = sys.getElementById(backButtonElements[i]);
127
+
128
+ backButtonHtmlElement.onclick = backButtonElementOnClick;
129
+ }
130
+
131
+ var nextButtonElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.NextButton);
132
+ nextButtonElement.onclick = function () { client._refineAddress(dataSetElement.value, refineElement.value, configuration); };
133
+ };
134
+
135
+ ExperianDataQuality.DataQuality.Address.Client.prototype._isExistingAddressEdited = function _isExistingAddressEdited(configuration) {
136
+ var sys = ExperianDataQuality.system;
137
+ var dq = ExperianDataQuality.DataQuality;
138
+
139
+ var areAllFieldsEmpty = true;
140
+
141
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
142
+ var inputMapping = configuration._inputMappings[i];
143
+
144
+ var value = dq.Client.collectValuesFromInputMapping(inputMapping);
145
+
146
+ switch (inputMapping.edqFieldName) {
147
+ case dq.Line1:
148
+ case dq.Line2:
149
+ case dq.Line3:
150
+ case dq.Line4:
151
+ case dq.Line5:
152
+ if (!sys.isNullOrEmpty(value)) {
153
+ areAllFieldsEmpty = false;
154
+ }
155
+ dq.Snapshot[inputMapping.edqFieldName] = value;
156
+ break;
157
+ default:
158
+ break;
159
+ }
160
+
161
+ //if(!areAllFieldsEmpty) { break;}
162
+ }
163
+
164
+ return areAllFieldsEmpty;
165
+ };
166
+
167
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showPromptSetFor = function _showPromptSetFor(configuration, dataSet) {
168
+ var sys = ExperianDataQuality.system;
169
+ var dq = ExperianDataQuality.DataQuality;
170
+
171
+ if(dq.ManualEntryState === dq.Active) {
172
+ return;
173
+ }
174
+
175
+ var visibleElements;
176
+ if (sys.containsInArray(dataSet, dq.Address.LicensedDataSets)) {
177
+ switch(dataSet) {
178
+ case 'US':
179
+ case 'CA':
180
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.Line1, dq.Line2, dq.Line3, dq.Line4, dq.Line5];
181
+ break;
182
+ case 'GB':
183
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Postcode, dq.UnknownPostCode];
184
+ break;
185
+ case 'DE':
186
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Postcode, dq.UnknownPostCode, dq.Street];
187
+ break;
188
+ case 'IE':
189
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Town, dq.Street];
190
+ break;
191
+ }
192
+ if( dq.Address.Configuration.IsManualEntryAllowed) { visibleElements.push(dq.ManualEntry); }
193
+ }
194
+ else {
195
+ visibleElements = [dq.Line1, dq.Line2, dq.Line3, dq.Line4, dq.Line5, dq.DataSet];
196
+ }
197
+
198
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, visibleElements);
199
+ this._handleErrorMessage(configuration, dq.ErrorMessage);
200
+ configuration.stage = dq.WorkFlowStages.Input;
201
+ };
202
+
203
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showUnknownPostcodePromptSet = function _showUnknownPostcodePromptSet(configuration, dataSet) {
204
+ var dq = ExperianDataQuality.DataQuality;
205
+
206
+ if(dq.ManualEntryState === dq.Active) {
207
+ return;
208
+ }
209
+
210
+ var visibleElements;
211
+ if(dataSet === 'GB' || dataSet === 'DE') {
212
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.ManualEntry, dq.Town, dq.Street, dq.KnownPostCode];
213
+ }
214
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, visibleElements);
215
+ configuration.stage = dq.WorkFlowStages.Input;
216
+ };
217
+
218
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showSuggestionsProptset = function _showSuggestionsProptset(configuration) {
219
+ var dq = ExperianDataQuality.DataQuality;
220
+
221
+ if(dq.ManualEntryState === dq.Active) {
222
+ return;
223
+ }
224
+
225
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.BackButton, dq.SelectButton, dq.Suggestions, dq.ManualEntry]);
226
+ configuration.stage = dq.WorkFlowStages.Suggestions;
227
+ };
228
+
229
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showRefineInputPromptSet = function _showRefineInputPromptSet(configuration) {
230
+ var dq = ExperianDataQuality.DataQuality;
231
+
232
+ if(dq.ManualEntryState === dq.Active) {
233
+ return;
234
+ }
235
+
236
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.MatchType, dq.RefineInput, dq.BackButton, dq.NextButton, dq.ManualEntry]);
237
+ configuration.stage = dq.WorkFlowStages.Refining;
238
+ };
239
+
240
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showVerifiedAddressPromptSet = function _showVerifiedAddressPromptSet(configuration, isVerified, dataSet) {
241
+ var dq = ExperianDataQuality.DataQuality;
242
+
243
+ if(dq.ManualEntryState === dq.Active) {
244
+ return;
245
+ }
246
+
247
+ var vasableElements = [dq.Line1, dq.Line2, dq.Line3, dq.Line4, dq.Line5, dq.DataSet];
248
+
249
+ if(isVerified) {
250
+ configuration.stage = dq.WorkFlowStages.Verified;
251
+ vasableElements.push(dq.BackButton);
252
+ } else {
253
+ vasableElements.push(dq.ChangeAddressButton);
254
+ }
255
+
256
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, vasableElements);
257
+ };
258
+
259
+ ExperianDataQuality.DataQuality.Address.Client.prototype._findAddress = function _findAddress(configuration) {
260
+ var sys = ExperianDataQuality.system;
261
+ var dq = ExperianDataQuality.DataQuality;
262
+
263
+ var parameters = {};
264
+ var areAllFieldsEmpty = true;
265
+
266
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
267
+ var inputMapping = configuration._inputMappings[i];
268
+
269
+ var value = dq.Client.collectValuesFromInputMapping(inputMapping);
270
+ //TBD
271
+ switch (inputMapping.edqFieldName) {
272
+ case dq.DataSet:
273
+ case dq.Street:
274
+ case dq.BuildingNumber:
275
+ case dq.Town:
276
+ case dq.Postcode:
277
+ case dq.Line1:
278
+ case dq.Line2:
279
+ case dq.Line3:
280
+ case dq.Line4:
281
+ case dq.Line5:
282
+ if (inputMapping.edqFieldName !== dq.DataSet && !sys.isNullOrEmpty(value)) {
283
+ areAllFieldsEmpty = false;
284
+ }
285
+ parameters[inputMapping.edqFieldName] = value;
286
+ dq.Snapshot[inputMapping.edqFieldName] = value;
287
+ break;
288
+ default:
289
+ break;
290
+ }
291
+ }
292
+
293
+ if (areAllFieldsEmpty) {
294
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
295
+ return;
296
+ }
297
+
298
+ this._executeFindAddressRequest(configuration, parameters, dq.Address.Configuration.SearchServiceUrl);
299
+ };
300
+
301
+ ExperianDataQuality.DataQuality.Address.Client.prototype._refineAddress = function _refineAddress(dataSet, refineInput, configuration) {
302
+ var sys = ExperianDataQuality.system;
303
+ var dq = ExperianDataQuality.DataQuality;
304
+
305
+ if (sys.isNullOrEmpty(refineInput)) {
306
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
307
+ return;
308
+ }
309
+
310
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
311
+ if (sys.isNull(suggestionsHtmlElement) || sys.isNull(suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex])) {
312
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
313
+ return;
314
+ }
315
+
316
+ var partialText = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].innerHTML;
317
+ var unresolvableRange = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['range'].value;
318
+
319
+ if (!this._validateRefinementInput(refineInput, partialText, unresolvableRange)) {
320
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage, configuration);
321
+ return;
322
+ }
323
+
324
+ var parameters = {};
325
+ parameters[dq.Moniker] = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].value;
326
+ parameters[dq.RefineInput] = refineInput;
327
+ parameters[dq.DataSet] = dataSet;
328
+
329
+ dq.Snapshot[dq.RefineInput] = refineInput;
330
+
331
+ this._executeFindAddressRequest(configuration, parameters, dq.Address.Configuration.RefineServiceUrl);
332
+ };
333
+
334
+ ExperianDataQuality.DataQuality.Address.Client.prototype._validateRefinementInput = function _validateRefinementInput(refineInput, partialAddress, unresolvableRange) {
335
+ var dq = ExperianDataQuality.DataQuality;
336
+ var sys = ExperianDataQuality.system;
337
+
338
+ if (refineInput.length > 40) { return false; }
339
+
340
+ if (!sys.toBoolean(unresolvableRange)) { return true; }
341
+
342
+ var range = partialAddress.match(/[0-9a-zA-Z]+\s[...]+\s[0-9a-zA-Z]+/gim)[0].split('...');
343
+ if (range.length > 2) {
344
+ return true;
345
+ }
346
+
347
+ var startRange = isNaN(parseInt(range[0].trim())) ? range[0].trim() : parseInt(range[0].trim());
348
+ var endRange = isNaN(parseInt(range[1].trim())) ? range[1].trim() : parseInt(range[1].trim());
349
+ var castedInput = isNaN(parseInt(refineInput.trim())) ? refineInput.trim() : parseInt(refineInput.trim());
350
+
351
+ var isValid = true;
352
+ if (castedInput < startRange || castedInput > endRange) {
353
+ isValid = false;
354
+ } else {
355
+ var criteria = partialAddress.substr(partialAddress.indexOf('['), partialAddress.indexOf(']'));
356
+
357
+ if (sys.isNullOrEmpty(criteria) && isNaN(castedInput)) {
358
+ isValid = false;
359
+ } else {
360
+ if (sys.beginsWith('[even]', criteria) || sys.endsWith('[even]', criteria)) {
361
+ isValid = (!isNaN(castedInput % 2) && castedInput % 2 === 0);
362
+ }
363
+ if (sys.beginsWith('[odd]', criteria) || sys.endsWith('[odd]', criteria)) {
364
+ isValid = (!isNaN(castedInput % 2) && castedInput % 2 !== 0);
365
+ }
366
+ }
367
+ }
368
+
369
+ return isValid;
370
+ };
371
+
372
+ ExperianDataQuality.DataQuality.Address.Client.prototype._executeFindAddressRequest = function _executeFindAddressRequest(configuration, parameters, url) {
373
+ var sys = ExperianDataQuality.system;
374
+ var dq = ExperianDataQuality.DataQuality;
375
+ var addressClient = dq.Address.Client;
376
+
377
+ var client = this;
378
+
379
+ client._handleLoader(configuration, true);
380
+ this._executeXMLHttpRequest(url, parameters, function (response, errorMessage, xhr) {
381
+ client._handleLoader(configuration, false);
382
+
383
+ if (!sys.isNullOrEmpty(errorMessage)) {
384
+ client._promptSetForErrorMessage(errorMessage, configuration);
385
+ return;
386
+ }
387
+
388
+ if(!sys.isNull(response.AddressLineDictionary)) {
389
+ client.setValues(response.AddressLineDictionary, configuration);
390
+ client._showVerifiedAddressPromptSet(configuration, true, parameters[dq.DataSet]);
391
+ return;
392
+ }
393
+
394
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
395
+ var matchType = !sys.isNull(response.MatchType) ? response.MatchType : '';
396
+
397
+ if(response.Total >= 2) {
398
+ var suggestionsHtmlElementLabel = configuration._getHtmlElementLabelFromInputMappingByEdqFieldName(dq.Suggestions);
399
+ suggestionsHtmlElementLabel.innerHTML = response.Prompt === 'Enter selection' ? ExperianDataQuality.DataQuality.Address.EnterSelection : 'Enter selection';
400
+
401
+ addressClient.populateSuggestionList(suggestionsHtmlElement, response.PickListEntries, matchType);
402
+ client._showSuggestionsProptset(configuration);
403
+ }
404
+ else {
405
+ var details = response.PickListEntries[0];
406
+
407
+ if (details && details.PickList === 'No matches' || details.PickList === 'Search cancelled (too many matches)') {
408
+ details.PickList = details.PickList === 'No matches' ? ExperianDataQuality.DataQuality.Address.NoMatchesMessage : ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage;
409
+ client._showErrorMessage(details.PickList, configuration);
410
+ return;
411
+ }
412
+
413
+ if(details.FullAddress) {
414
+ client._getAddress(parameters[dq.DataSet], details.Moniker, configuration);
415
+ return;
416
+ }
417
+
418
+ addressClient.populateSuggestionList(suggestionsHtmlElement, response.PickListEntries, response.Prompt);
419
+ suggestionsHtmlElement.options[0].selected = true;
420
+ client._selectAddress(parameters[dq.DataSet], configuration);
421
+ }
422
+ });
423
+ };
424
+
425
+ ExperianDataQuality.DataQuality.Address.Client.populateSuggestionList = function populateSuggestionList(suggestionsHtmlElement, options, matchType) {
426
+ var sys = ExperianDataQuality.system;
427
+ var dq = ExperianDataQuality.DataQuality;
428
+
429
+ suggestionsHtmlElement.innerHTML = '';
430
+ for (var i = 0; i < options.length; i++) {
431
+ var element = document.createElement(dq.HtmlTags.Option);
432
+ element.innerHTML = options[i].PickList + ' ' + options[i].Postcode;
433
+ element.textContent = options[i].PickList + ' ' + options[i].Postcode;
434
+ element.value = options[i].Moniker;
435
+ element.setAttribute('range', options[i].UnresolvableRange);
436
+ element.setAttribute('full', options[i].FullAddress);
437
+ if(!sys.isNullOrEmpty(matchType)) {
438
+ element.setAttribute('matchtype', matchType);
439
+ }
440
+ suggestionsHtmlElement.appendChild(element);
441
+ }
442
+ };
443
+
444
+ ExperianDataQuality.DataQuality.Address.Client.clearSuggestionList = function clearSuggestionList(suggestionsHtmlElement) {
445
+ if (suggestionsHtmlElement === null) { return; }
446
+ if (suggestionsHtmlElement.options === null) { return; }
447
+ while (suggestionsHtmlElement.options.length > 0) {
448
+ suggestionsHtmlElement.remove(0);
449
+ }
450
+ suggestionsHtmlElement.multiple = true;
451
+ };
452
+
453
+ ExperianDataQuality.DataQuality.Address.Client.prototype._selectAddress = function _selectAddress(dataSet, configuration) {
454
+ var sys = ExperianDataQuality.system;
455
+ var dq = ExperianDataQuality.DataQuality;
456
+
457
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
458
+
459
+ if (sys.isNull(suggestionsHtmlElement) || suggestionsHtmlElement.selectedIndex === -1) {
460
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions, configuration);
461
+ return;
462
+ }
463
+
464
+ var isFullAddress = sys.toBoolean(suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['full'].value);
465
+ if (isFullAddress) {
466
+ var moniker = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].value;
467
+ this._getAddress(dataSet, moniker, configuration);
468
+ } else {
469
+
470
+ var refineInputHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.RefineInput);
471
+ var refineInputHtmlElementLabel = configuration._getHtmlElementLabelFromInputMappingByEdqFieldName(dq.RefineInput);
472
+ var refineInputHtmlElementMatchType = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.MatchType);
473
+ var matchType = '';
474
+ if(dataSet === 'US' || dataSet === 'CA') {
475
+ matchType = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['matchtype'].value;
476
+ }
477
+
478
+ var matchTypeMessage = '';
479
+ switch(matchType) {
480
+ case 'InteractionRequired':
481
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.InteractionRequired;
482
+ break;
483
+ case 'PremisesPartial':
484
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.PremisesPartial;
485
+ break;
486
+ case 'StreetPartial':
487
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.StreetPartial;
488
+ break;
489
+ case 'AptAppend':
490
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.AptAppend;
491
+ break;
492
+ case 'Multiple':
493
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.Multiple;
494
+ break;
495
+ case 'None':
496
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.None;
497
+ break;
498
+ default:
499
+ matchTypeMessage = ExperianDataQuality.DataQuality.Address.RefinementText;
500
+ break;
501
+ }
502
+ refineInputHtmlElementMatchType.innerHTML = '<b>' + matchTypeMessage + '</b>';
503
+ refineInputHtmlElementLabel.innerHTML = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].innerHTML;
504
+ this._showRefineInputPromptSet(configuration);
505
+ setTimeout(function() { refineInputHtmlElement.focus(); }, 1);
506
+ }
507
+ };
508
+
509
+ ExperianDataQuality.DataQuality.Address.Client.prototype._getAddress = function _getAddress(dataSet, moniker, configuration) {
510
+ var sys = ExperianDataQuality.system;
511
+ var dq = ExperianDataQuality.DataQuality;
512
+
513
+ var dataSetElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.DataSet);
514
+ var currentAddressId = dataSetElement.id.replace(/[^\d.]/g, '');
515
+
516
+ var parameters = {};
517
+ parameters[dq.Moniker] = moniker;
518
+ parameters[dq.DataSet] = dataSet;
519
+ parameters['address_id'] = currentAddressId;
520
+
521
+
522
+ var client = this;
523
+ client._handleLoader(configuration, true);
524
+ this._executeXMLHttpRequest(dq.Address.Configuration.GetAddressServiceUrl, parameters, function (response, errorMessage, xhr) {
525
+ client._handleLoader(configuration, false);
526
+
527
+ if (!sys.isNullOrEmpty(errorMessage)) {
528
+ client._promptSetForErrorMessage(errorMessage, configuration);
529
+ return;
530
+ }
531
+
532
+ client.setValues(response.AddressLineDictionary, configuration);
533
+ client._showVerifiedAddressPromptSet(configuration, true, dataSet);
534
+ });
535
+ };
536
+
537
+ ExperianDataQuality.DataQuality.Address.Client.prototype._promptSetForErrorMessage = function _promptSetForErrorMessage(errorMessage, configuration) {
538
+ var dq = ExperianDataQuality.DataQuality;
539
+
540
+ this._showErrorMessage(errorMessage, configuration);
541
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.ManualEntry, dq.BackButton, dq.TryAgain, dq.ErrorMessage]);
542
+ };
543
+
544
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showErrorMessage = function _showErrorMessage(message, configuration) {
545
+ var dq = ExperianDataQuality.DataQuality;
546
+ var sys = ExperianDataQuality.system;
547
+
548
+ var errorMessageOutputMapping = configuration._getOutputMappingByEdqFieldName(dq.ErrorMessage);
549
+ var errorMessageHtmlElement = sys.getElementById(errorMessageOutputMapping.htmlElementId);
550
+ if (sys.isNull(errorMessageHtmlElement)) {
551
+ return;
552
+ }
553
+
554
+ if (errorMessageHtmlElement.tagName === dq.HtmlTags.Label || errorMessageHtmlElement.tagName === dq.HtmlTags.Div) {
555
+ errorMessageHtmlElement.innerHTML = message;
556
+ } else {
557
+ errorMessageHtmlElement.value = message;
558
+ }
559
+ dq.Client.showElement(errorMessageHtmlElement);
560
+ };
561
+
562
+ ExperianDataQuality.DataQuality.Address.Client.prototype._restoreInputValues = function _restoreInputValues(mapping) {
563
+ var dq = ExperianDataQuality.DataQuality;
564
+ var sys = ExperianDataQuality.system;
565
+
566
+ for (var i = 0, max = mapping.length; i < max; i++) {
567
+ var field = sys.getElementById(mapping[i].htmlElementIds[0]);
568
+ if (sys.isNull(field)) {
569
+ continue;
570
+ }
571
+
572
+ switch (mapping[i].edqFieldName) {
573
+ case dq.DataSet:
574
+ case dq.Street:
575
+ case dq.City:
576
+ case dq.Town:
577
+ case dq.State:
578
+ case dq.Postcode:
579
+ case dq.BuildingNumber:
580
+ case dq.Postcode:
581
+ case dq.RefineInput:
582
+ case dq.Line1:
583
+ case dq.Line2:
584
+ case dq.Line3:
585
+ case dq.Line4:
586
+ case dq.Line5:
587
+ if (dq.Snapshot[mapping[i].edqFieldName] !== undefined) {
588
+ field.value = dq.Snapshot[mapping[i].edqFieldName];
589
+ }
590
+ break;
591
+ default:
592
+ continue;
593
+ }
594
+ }
595
+ };
596
+
597
+ ExperianDataQuality.DataQuality.Address.Client.prototype._handleLoader = function _handleLoader(configuration, showLoader) {
598
+ var dq = ExperianDataQuality.DataQuality;
599
+ var sys = ExperianDataQuality.system;
600
+
601
+ var loader = null;
602
+ this._handleErrorMessage(configuration, dq.ErrorMessage);
603
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
604
+ var fieldName = configuration._inputMappings[i].edqFieldName;
605
+ var htmlElement = null;
606
+
607
+ if(fieldName === dq.BackButton) {
608
+ htmlElement = configuration._getHtmlElementsFromInputMappingByEdqFieldName(fieldName);
609
+ } else {
610
+ htmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(fieldName);
611
+ }
612
+
613
+ if(sys.isArray(htmlElement)) {
614
+ for(var j = 0, max2 = htmlElement.length; j < max2; j++) {
615
+ var element = sys.getElementById(htmlElement[j]);
616
+
617
+ if (sys.isNull(element)) {
618
+ continue;
619
+ }
620
+
621
+ if(element.tagName === dq.HtmlTags.Button || element.tagName === dq.HtmlTags.Select) {
622
+ element.disabled = showLoader ? true : false;
623
+ }
624
+ }
625
+ } else {
626
+ if (sys.isNull(htmlElement)) {
627
+ continue;
628
+ }
629
+
630
+ if(htmlElement.tagName === dq.HtmlTags.Button || htmlElement.tagName === dq.HtmlTags.Select) {
631
+ htmlElement.disabled = showLoader ? true : false;
632
+ }
633
+ }
634
+
635
+ if(fieldName === dq.Loader) {
636
+ loader = htmlElement;
637
+ }
638
+
639
+ if(fieldName === dq.UnknownPostCode || fieldName === dq.KnownPostCode) {
640
+ if(showLoader) {
641
+ htmlElement.oldEvent = htmlElement.onclick;
642
+ htmlElement.onclick = null;
643
+ } else {
644
+ if(htmlElement.onclick === null) {
645
+ htmlElement.onclick = htmlElement.oldEvent;
646
+ }
647
+ }
648
+ }
649
+ }
650
+
651
+ if(showLoader) {
652
+ dq.Client.showElement(loader);
653
+ } else {
654
+ dq.Client.hideElement(loader);
655
+ }
656
+ };
657
+
658
+ ExperianDataQuality.DataQuality.Address.InteractionRequired = ExperianDataQuality.DataQuality.Address.InteractionRequired || 'We recommend:';
659
+ ExperianDataQuality.DataQuality.Address.PremisesPartial = ExperianDataQuality.DataQuality.Address.PremisesPartial || 'Confirm your Apartment/Suite/Unit number:';
660
+ ExperianDataQuality.DataQuality.Address.StreetPartial = ExperianDataQuality.DataQuality.Address.StreetPartial || 'Confirm your House/Building number:';
661
+ ExperianDataQuality.DataQuality.Address.AptAppend = ExperianDataQuality.DataQuality.Address.AptAppend || 'Confirm your House/Building number:';
662
+ ExperianDataQuality.DataQuality.Address.Multiple = ExperianDataQuality.DataQuality.Address.Multiple || 'Our suggested matches:';
663
+ ExperianDataQuality.DataQuality.Address.None = ExperianDataQuality.DataQuality.Address.None || 'No Match';
664
+
665
+ ExperianDataQuality.DataQuality.Address.LicensedDataSets = ExperianDataQuality.DataQuality.Address.LicensedDataSets || [];
666
+ ExperianDataQuality.DataQuality.Address.EnterSelection = ExperianDataQuality.DataQuality.Address.EnterSelection || 'Enter selection';
667
+ ExperianDataQuality.DataQuality.Address.RefinementText = ExperianDataQuality.DataQuality.Address.RefinementText || 'Your selection covers a range of addresses. Enter your exact details:';
668
+ ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage = ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage || 'Search cancelled (too many matches)';
669
+ ExperianDataQuality.DataQuality.Address.NoMatchesMessage = ExperianDataQuality.DataQuality.Address.NoMatchesMessage || 'No matches';
670
+ ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions = ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions || "Please select a suggestion.";
671
+ ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage = ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage || "Please enter exact details.";
672
+ ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage = ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage || "This address is outside of the range. Please try again or click Back and select the correct range.";
skin/adminhtml/default/default/ExperianDataQuality/js/edqClient.js ADDED
@@ -0,0 +1,565 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var ExperianDataQuality = ExperianDataQuality || {};
2
+ ExperianDataQuality.DataQuality = ExperianDataQuality.DataQuality || {};
3
+ ExperianDataQuality.DataQuality.HtmlTags = ExperianDataQuality.DataQuality.HtmlTags || {};
4
+
5
+ //Configuration_Start
6
+ ExperianDataQuality.DataQuality.Configuration = function Configuration(inputMappings, outputMappings, type) {
7
+ this._inputMappings = inputMappings || [];
8
+ this._outputMappings = outputMappings || [];
9
+ this._type = type;
10
+ };
11
+
12
+ ExperianDataQuality.DataQuality.Configuration.prototype.addInputMapping = function addInputMapping(edqFieldName, htmlElementId) {
13
+ var sys = ExperianDataQuality.system;
14
+ var dq = ExperianDataQuality.DataQuality;
15
+
16
+ var mapping = this.getInputMappingByEdqFieldName(edqFieldName);
17
+ if (!sys.isNull(mapping)) {
18
+ mapping.addHtmlElementId(htmlElementId);
19
+ } else {
20
+ mapping = new dq.InputMapping(edqFieldName, htmlElementId);
21
+ this._inputMappings.push(mapping);
22
+ };
23
+ };
24
+
25
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementLabelFromInputMappingByEdqFieldName = function _getHtmlElementLabelFromInputMappingByEdqFieldName(edqFieldName) {
26
+ var sys = ExperianDataQuality.system;
27
+ var dq = ExperianDataQuality.DataQuality;
28
+
29
+ var htmlElement = this._getHtmlElementFromInputMappingByEdqFieldName(edqFieldName);
30
+ if (sys.isNull(htmlElement)) {
31
+ return undefined;
32
+ }
33
+
34
+ return sys.getElementLabelById(htmlElement.id);
35
+ };
36
+
37
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementFromInputMappingByEdqFieldName = function _getHtmlElementFromInputMappingByEdqFieldName(edqFieldName) {
38
+ var sys = ExperianDataQuality.system;
39
+ var dq = ExperianDataQuality.DataQuality;
40
+
41
+ var inputMapping = this.getInputMappingByEdqFieldName(edqFieldName);
42
+
43
+ if (sys.isNull(inputMapping) || inputMapping.htmlElementIds.length === 0) {
44
+ return undefined;
45
+ }
46
+
47
+ return sys.getElementById(inputMapping.htmlElementIds[0]);
48
+ };
49
+
50
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementsFromInputMappingByEdqFieldName = function _getHtmlElementsFromInputMappingByEdqFieldName(edqFieldName) {
51
+ var sys = ExperianDataQuality.system;
52
+ var dq = ExperianDataQuality.DataQuality;
53
+
54
+ var inputMapping = this.getInputMappingByEdqFieldName(edqFieldName);
55
+
56
+ if (sys.isNull(inputMapping) || inputMapping.htmlElementIds.length === 0) {
57
+ return undefined;
58
+ }
59
+
60
+ return inputMapping.htmlElementIds;
61
+ };
62
+
63
+ ExperianDataQuality.DataQuality.Configuration.prototype.getInputMappingByEdqFieldName = function getInputMappingByEdqFieldName(edqFieldName) {
64
+ var sys = ExperianDataQuality.system;
65
+
66
+ if (this._inputMappings.length === 0) {
67
+ return undefined;
68
+ }
69
+
70
+ for (var i = 0, max = this._inputMappings.length; i < max; i++) {
71
+ if (this._inputMappings[i].edqFieldName === edqFieldName) {
72
+ return this._inputMappings[i];
73
+ }
74
+ }
75
+ };
76
+
77
+ ExperianDataQuality.DataQuality.Configuration.prototype.addOutputMapping = function addOutputMapping(htmlElementId, edqFieldName) {
78
+ var sys = ExperianDataQuality.system;
79
+ var dq = ExperianDataQuality.DataQuality;
80
+
81
+ var mapping = this.getOutputMappingByHtmlElementId(htmlElementId);
82
+ if (!sys.isNull(mapping)) {
83
+ mapping.addEdqFieldName(edqFieldName);
84
+ } else {
85
+ mapping = new dq.OutputMapping(htmlElementId, edqFieldName);
86
+ this._outputMappings.push(mapping);
87
+ };
88
+ };
89
+
90
+ ExperianDataQuality.DataQuality.Configuration.prototype.getOutputMappingByHtmlElementId = function getOutputMappingByHtmlElementId(htmlElementId) {
91
+ var sys = ExperianDataQuality.system;
92
+
93
+ if (this._outputMappings.length === 0) {
94
+ return undefined;
95
+ }
96
+ for (var i = 0, max = this._outputMappings.length; i < max; i++) {
97
+ if (this._outputMappings[i].htmlElementId === htmlElementId) {
98
+ return this._outputMappings[i];
99
+ }
100
+ }
101
+ };
102
+
103
+ ExperianDataQuality.DataQuality.Configuration.prototype._getOutputMappingByEdqFieldName = function _getOutputMappingByEdqFieldName(edqFieldName) {
104
+ var sys = ExperianDataQuality.system;
105
+
106
+ if (this._outputMappings.length === 0) {
107
+ return undefined;
108
+ }
109
+
110
+ for (var i = 0, max = this._outputMappings.length; i < max; i++) {
111
+ for (var j = 0, total = this._outputMappings[i].edqFieldNames.length; j < total; j++) {
112
+ if (this._outputMappings[i].edqFieldNames[j] === edqFieldName) {
113
+ return this._outputMappings[i];
114
+ }
115
+ }
116
+ }
117
+
118
+ return undefined;
119
+ };
120
+ //Configuration_End
121
+
122
+ //Mapping_Start
123
+ ExperianDataQuality.DataQuality.InputMapping = function InputMapping(edqFieldName, htmlElementIdOrIds) {
124
+ var sys = ExperianDataQuality.system;
125
+
126
+ this.edqFieldName = edqFieldName;
127
+ if (sys.isArray(htmlElementIdOrIds)) {
128
+ this.htmlElementIds = htmlElementIdOrIds;
129
+ }
130
+ else {
131
+ this.htmlElementIds = new Array();
132
+
133
+ if(edqFieldName === 'Line4') {
134
+ this.htmlElementIds = [htmlElementIdOrIds];
135
+ }
136
+ else {
137
+ this.addHtmlElementId(htmlElementIdOrIds);
138
+ }
139
+ }
140
+ };
141
+
142
+ ExperianDataQuality.DataQuality.InputMapping.prototype.addHtmlElementId = function addHtmlElementId(htmlElementId) {
143
+ var sys = ExperianDataQuality.system;
144
+
145
+ if (sys.isNull(htmlElementId) || typeof htmlElementId !== "string") {
146
+ throw "Invalid htmlElementId value: " + htmlElementId;
147
+ }
148
+
149
+ if (!sys.contains(htmlElementId, this.htmlElementIds)) {
150
+ this.htmlElementIds = [htmlElementId];
151
+ }
152
+ };
153
+
154
+ ExperianDataQuality.DataQuality.OutputMapping = function OutputMapping(htmlElementId, edqFieldNameOrNames) {
155
+ var sys = ExperianDataQuality.system;
156
+
157
+ this.htmlElementId = htmlElementId;
158
+ if (sys.isArray(edqFieldNameOrNames)) {
159
+ this.edqFieldNames = edqFieldNameOrNames;
160
+ } else {
161
+ this.edqFieldNames = [];
162
+ this.addEdqFieldName(edqFieldNameOrNames);
163
+ };
164
+ };
165
+
166
+ ExperianDataQuality.DataQuality.OutputMapping.prototype.addEdqFieldName = function addEdqFieldName(edqFieldName) {
167
+ var sys = ExperianDataQuality.system;
168
+
169
+ if (sys.isNull(edqFieldName) || !sys.isString(edqFieldName)) {
170
+ throw "Invalid edqFieldName value. edqFieldName is either null, undefined or not a string";
171
+ }
172
+
173
+ if (!sys.contains(edqFieldName, this.edqFieldNames)) {
174
+ this.edqFieldNames.push(edqFieldName);
175
+ }
176
+ };
177
+ //Mapping_End
178
+
179
+ //Client_Start
180
+ ExperianDataQuality.DataQuality.Client = function Client(configurations) {
181
+ this._configurations = configurations || [];
182
+ };
183
+
184
+ ExperianDataQuality.DataQuality.Client.prototype.addConfiguration = function addConfiguration(configuration) {
185
+ var sys = ExperianDataQuality.system;
186
+
187
+ if (sys.isNull(configuration)) {
188
+ return;
189
+ }
190
+
191
+ if (!sys.contains(configuration, this._configurations)) {
192
+ this._configurations.push(configuration);
193
+ }
194
+ };
195
+
196
+ ExperianDataQuality.DataQuality.Client.prototype.initialize = function initialize() {
197
+ var sys = ExperianDataQuality.system;
198
+ var dq = ExperianDataQuality.DataQuality;
199
+
200
+ for (var i = 0, max = this._configurations.length; i < max; i++) {
201
+ this._initializeForConfiguration(this._configurations[i]);
202
+ }
203
+ };
204
+
205
+ ExperianDataQuality.DataQuality.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) { };
206
+
207
+ ExperianDataQuality.DataQuality.Client.prototype._hideAllInputMappingElementsExcept = function _hideAllInputMappingElementsExcept(inputMappings, edqFields) {
208
+ var sys = ExperianDataQuality.system;
209
+ var dq = ExperianDataQuality.DataQuality;
210
+
211
+ for (var j = 0, max = inputMappings.length; j < max; j++) {
212
+ var edqField = inputMappings[j].edqFieldName;
213
+
214
+ for(var k = 0, max2 = inputMappings[j].htmlElementIds.length; k < max2; k++) {
215
+
216
+ var showElement = sys.containsInArray(edqField, edqFields);
217
+
218
+ var elementId = inputMappings[j].htmlElementIds[k];
219
+
220
+ if(showElement === true) {
221
+ if(edqField === dq.BackButton) {
222
+ var backButtonIdSuffix = "";
223
+ if(sys.containsInArray(dq.Suggestions, edqFields)) {
224
+ backButtonIdSuffix = "suggestions";
225
+ } else if(sys.containsInArray(dq.TryAgain, edqFields)) {
226
+ backButtonIdSuffix = "tryagain";
227
+ } else if(sys.containsInArray(dq.NextButton, edqFields)) {
228
+ backButtonIdSuffix = "next";
229
+ }
230
+
231
+ if(backButtonIdSuffix !== "" && !sys.endsWith(backButtonIdSuffix, elementId)) {
232
+ showElement = false;
233
+ }
234
+ }
235
+ }
236
+
237
+ if (showElement) {
238
+ this._showElementAndLabel(elementId);
239
+ } else {
240
+ this._hideElementAndLabel(elementId);
241
+ }
242
+
243
+ }
244
+ }
245
+ };
246
+
247
+ ExperianDataQuality.DataQuality.Client.prototype._executeXMLHttpRequest = function _executeXMLHttpRequest(url, parameters, callback) {
248
+ var sys = ExperianDataQuality.system;
249
+
250
+ var xhr;
251
+
252
+ if(typeof XMLHttpRequest !== 'undefined') {
253
+ xhr = new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
254
+ } else {
255
+ var versions = ["MSXML2.XmlHttp.5.0",
256
+ "MSXML2.XmlHttp.4.0",
257
+ "MSXML2.XmlHttp.3.0",
258
+ "MSXML2.XmlHttp.2.0",
259
+ "Microsoft.XmlHttp"]; // code for IE6, IE5
260
+
261
+ for(var i = 0, max = versions.length; i < max; i++) {
262
+ try {
263
+ xhr = new ActiveXObject(versions[i]);
264
+ break;
265
+ } catch(e){
266
+ continue;
267
+ }
268
+ }
269
+ }
270
+
271
+ xhr.onreadystatechange = function ensureReadiness() {
272
+ if(xhr.readyState < 4 || xhr.status !== 200) {
273
+ if (xhr.status && xhr.status === 404)
274
+ {
275
+ callback('', xhr.statusText, xhr);
276
+ }
277
+ return;
278
+ }
279
+
280
+ if (xhr.readyState === 4) {
281
+ var response;
282
+ var errorMessage;
283
+
284
+ try {
285
+ response = JSON.parse(xhr.responseText);
286
+ errorMessage = response.error;
287
+ } catch (error) {
288
+ sys.logError(error);
289
+ errorMessage = "Invalid response";
290
+ }
291
+
292
+
293
+ callback(response, errorMessage, xhr);
294
+ }
295
+ };
296
+
297
+ xhr.open("POST", url, true);
298
+ xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
299
+ xhr.setRequestHeader('Accept', 'application/json, text/html, application/xml, text/xml, */*');
300
+ xhr.ontimeout = function () { callback('', 'Operation timed out.', xhr); };
301
+
302
+ var requestString = 'form_key' + '=' + window.FORM_KEY + '&';
303
+ for(var parameter in parameters) {
304
+ requestString += parameter + '=' + encodeURIComponent(parameters[parameter]) + '&';
305
+ }
306
+
307
+ xhr.send(requestString);
308
+
309
+ if (xhr.status && xhr.status === 404)
310
+ {
311
+ callback('', xhr.statusText, xhr);
312
+ }
313
+ };
314
+
315
+ ExperianDataQuality.DataQuality.Client.prototype._showElementAndLabel = function _showElementAndLabel(elementId) {
316
+ this._executeActionOnElementAndLabel(elementId, ExperianDataQuality.DataQuality.Client.showElement);
317
+ };
318
+
319
+ ExperianDataQuality.DataQuality.Client.prototype._hideElementAndLabel = function _hideElementAndLabel(elementId) {
320
+ this._executeActionOnElementAndLabel(elementId, ExperianDataQuality.DataQuality.Client.hideElement);
321
+ };
322
+
323
+ ExperianDataQuality.DataQuality.Client.prototype._executeActionOnElementAndLabel = function _executeActionOnElementAndLabel(elementId, action) {
324
+ var sys = ExperianDataQuality.system;
325
+
326
+ var field = sys.getElementById(elementId);
327
+ if (!sys.isNull(field)) {
328
+ action(field);
329
+ }
330
+
331
+ var label = sys.getElementLabelById(elementId);
332
+ if(!sys.isNull(label)) {
333
+ action(label);
334
+ }
335
+ };
336
+
337
+ ExperianDataQuality.DataQuality.Client.prototype._handleErrorMessage = function _handleErrorMessage(configuration, edqFieldForMessage, message) {
338
+ var sys = ExperianDataQuality.system;
339
+ var dq = ExperianDataQuality.DataQuality;
340
+
341
+ var errorMessageLabelMapping = configuration._getOutputMappingByEdqFieldName(edqFieldForMessage);
342
+ if (!sys.isNullOrEmpty(errorMessageLabelMapping)) {
343
+ dq.Client._setValidationMessage(errorMessageLabelMapping.htmlElementId, message);
344
+ }
345
+ };
346
+
347
+ ExperianDataQuality.DataQuality.Client._setValidationMessage = function _setValidationMessage(textId, text) {
348
+ var sys = ExperianDataQuality.system;
349
+ var client = ExperianDataQuality.DataQuality.Client;
350
+
351
+ var validationMessageElement = sys.getElementById(textId);
352
+
353
+ if (!sys.isNull(validationMessageElement)) {
354
+ validationMessageElement.innerHTML = text;
355
+ validationMessageElement.style.display = sys.isNullOrEmpty(text) ? 'none' : 'inline';
356
+ }
357
+ };
358
+
359
+ ExperianDataQuality.DataQuality.Client.prototype.setValues = function setValues(result, configuration) {
360
+ var dq = ExperianDataQuality.DataQuality;
361
+ var sys = ExperianDataQuality.system;
362
+
363
+ if (!sys.isNull(result[dq.ErrorMessage])) { return; }
364
+
365
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
366
+ dq.Client._setValue(configuration._outputMappings[i], result, configuration._type);
367
+ }
368
+ };
369
+
370
+ ExperianDataQuality.DataQuality.Client._setValue = function _setValue(mapping, result, type) {
371
+ var sys = ExperianDataQuality.system;
372
+ var dq = ExperianDataQuality.DataQuality;
373
+
374
+ var client = dq.Client;
375
+
376
+ var val = '';
377
+ var edqFieldName = '';
378
+ for (var j = 0; j < mapping.edqFieldNames.length; j++) {
379
+ edqFieldName = mapping.edqFieldNames[j];
380
+ var fieldValue = result[edqFieldName];
381
+
382
+ if (sys.isNullOrEmpty(fieldValue)) {
383
+ continue;
384
+ };
385
+
386
+ if (val.length > 0) {
387
+ val += client.delimiter;
388
+ };
389
+
390
+ val += fieldValue;
391
+ }
392
+
393
+ if (edqFieldName === dq.Corrections) {
394
+ var returnMessage = sys.isNullOrEmpty(val) ? '' : '(Suggested: ' + val + ' )';
395
+ client._setValidationMessage(mapping.htmlElementId, returnMessage);
396
+ } else {
397
+ client.setElementValue(mapping.htmlElementId, val);
398
+ }
399
+ };
400
+ ExperianDataQuality.DataQuality.Client.delimiter = " ";
401
+
402
+ ExperianDataQuality.DataQuality.Client.setElementValue = function setElementValue(htmlElementId, value) {
403
+ var sys = ExperianDataQuality.system;
404
+
405
+ sys.setElementValue(htmlElementId, value);
406
+ };
407
+
408
+ ExperianDataQuality.DataQuality.Client.showElement = function showElement(element) {
409
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement(element, true);
410
+ };
411
+
412
+ ExperianDataQuality.DataQuality.Client.hideElement = function hideElement(element) {
413
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement(element, false);
414
+ };
415
+
416
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement = function _executeShowOrHideElementContainerOrElement(element, show) {
417
+ var dq = ExperianDataQuality.DataQuality;
418
+ var sys = ExperianDataQuality.system;
419
+ var client = dq.Client;
420
+
421
+ if (sys.isNull(element)) {
422
+ return;
423
+ }
424
+
425
+ if(element.tagName === dq.HtmlTags.Input && !show && !sys.beginsWith('address', element.name)) {
426
+ element.value = '';
427
+ }
428
+
429
+ if(element.tagName === dq.HtmlTags.Label || element.tagName === dq.HtmlTags.Div) {
430
+ element.style.display = show ? "" : "none";
431
+ }
432
+
433
+ var container = client._tryGetElementContainer(element);
434
+ if(!sys.isNull(container)) {
435
+ element = container;
436
+ }
437
+
438
+ element.style.display = show ? "" : "none";
439
+ };
440
+
441
+ ExperianDataQuality.DataQuality.Client._tryGetElementContainer = function _tryGetElementContainer(element) {
442
+ var client = ExperianDataQuality.DataQuality.Client;
443
+
444
+ var parentNodeOfElement = element.parentNode;
445
+ while(ExperianDataQuality.DataQuality.HtmlTags.TableRow !== parentNodeOfElement.nodeName) {
446
+ parentNodeOfElement = parentNodeOfElement.parentNode;
447
+ }
448
+
449
+ if (client._isContainerElement(parentNodeOfElement)) {
450
+ return parentNodeOfElement;
451
+ }
452
+
453
+ return undefined;
454
+ };
455
+
456
+ ExperianDataQuality.DataQuality.Client._isContainerElement = function _isContainerElement(element){
457
+ var dq = ExperianDataQuality.DataQuality;
458
+
459
+ if ((element.tagName === dq.HtmlTags.Div
460
+ || element.tagName === dq.HtmlTags.ListItem
461
+ || element.tagName === dq.HtmlTags.Span
462
+ || element.tagName === dq.HtmlTags.TableHeader
463
+ || element.tagName === dq.HtmlTags.TableData
464
+ || element.tagName === dq.HtmlTags.TableRow)) {
465
+ return true;
466
+ }
467
+
468
+ return false;
469
+ };
470
+
471
+ ExperianDataQuality.DataQuality.Client.collectValuesFromInputMapping = function collectValuesFromInputMapping(inputMapping) {
472
+ var sys = ExperianDataQuality.system;
473
+
474
+ value = '';
475
+ for (var i = 0, max = inputMapping.htmlElementIds.length; i < max; i++) {
476
+ var htmlElement = sys.getElementById(inputMapping.htmlElementIds[i]);
477
+
478
+ if (!sys.isNull(htmlElement) && !sys.isNullOrEmpty(htmlElement.value)) {
479
+ value += htmlElement.value + ' ';
480
+ }
481
+ }
482
+
483
+ return value.trim();
484
+ };
485
+
486
+ //Client_End
487
+ ExperianDataQuality.DataQuality.Active = 'Active';
488
+ ExperianDataQuality.DataQuality.Deactive = 'Deactive';
489
+ ExperianDataQuality.DataQuality.ManualEntryState = ExperianDataQuality.DataQuality.Deactive;
490
+
491
+ ExperianDataQuality.DataQuality.ConfigurationType = { Address: 3 };
492
+ ExperianDataQuality.DataQuality.WorkFlowStages = { Input: 0, Suggestions: 1, Refining: 2, Verified: 3 };
493
+
494
+ ExperianDataQuality.DataQuality.Number = 'Number';
495
+ ExperianDataQuality.DataQuality.AreaCode = 'DefaultCountryCode';
496
+ ExperianDataQuality.DataQuality.EmailAddress = 'EmailAddress';
497
+ ExperianDataQuality.DataQuality.Message = 'Message';
498
+ ExperianDataQuality.DataQuality.Certainty = 'Certainty';
499
+ ExperianDataQuality.DataQuality.Loader = 'Loader';
500
+ ExperianDataQuality.DataQuality.ErrorMessage = 'ErrorMessage';
501
+ ExperianDataQuality.DataQuality.ValidationStatusVerified = 'Verified';
502
+ ExperianDataQuality.DataQuality.ValidationStatusNotVerified = 'Not verified';
503
+ ExperianDataQuality.DataQuality.ValidationStatus = 'ValidationStatus';
504
+ ExperianDataQuality.DataQuality.Country = 'Country';
505
+ ExperianDataQuality.DataQuality.PhoneCountry = 'PhoneCountry';
506
+ ExperianDataQuality.DataQuality.Suggested = 'Suggested';
507
+ ExperianDataQuality.DataQuality.Corrections = 'Corrections';
508
+
509
+ ExperianDataQuality.DataQuality.DataSet = 'DataSet';
510
+ ExperianDataQuality.DataQuality.Street = 'Street1';
511
+ ExperianDataQuality.DataQuality.City = 'City';
512
+ ExperianDataQuality.DataQuality.StreetNumber = 'StreetNumber';
513
+ ExperianDataQuality.DataQuality.Postcode = 'Postcode';
514
+ ExperianDataQuality.DataQuality.State = 'State';
515
+ ExperianDataQuality.DataQuality.BuildingNumber = 'BuildingNumberOrName';
516
+ ExperianDataQuality.DataQuality.Town = 'Town';
517
+ ExperianDataQuality.DataQuality.FindAddressButton = 'FindAddressButton';
518
+ ExperianDataQuality.DataQuality.ChangeAddressButton = 'ChangeAddressButton';
519
+ ExperianDataQuality.DataQuality.BackButton = 'BackButton';
520
+ ExperianDataQuality.DataQuality.SelectButton = 'SelectButton';
521
+ ExperianDataQuality.DataQuality.NextButton = 'NextButton';
522
+ ExperianDataQuality.DataQuality.Suggestions = 'Suggestions';
523
+ ExperianDataQuality.DataQuality.UnknownPostCode = 'UnknownPostCode';
524
+ ExperianDataQuality.DataQuality.KnownPostCode = 'KnownPostCode';
525
+ ExperianDataQuality.DataQuality.RefineInput = 'Refinement';
526
+ ExperianDataQuality.DataQuality.ManualEntry = 'ManualEntry';
527
+ ExperianDataQuality.DataQuality.TryAgain = 'TryAgain';
528
+ ExperianDataQuality.DataQuality.Moniker = 'Moniker';
529
+ ExperianDataQuality.DataQuality.Layout = 'Layout';
530
+ ExperianDataQuality.DataQuality.PickList = 'PickList';
531
+ ExperianDataQuality.DataQuality.MatchType = 'MatchType';
532
+
533
+ ExperianDataQuality.DataQuality.Line1 = 'Line0';
534
+ ExperianDataQuality.DataQuality.Line2 = 'Line1';
535
+ ExperianDataQuality.DataQuality.Line3 = 'Line2';
536
+ ExperianDataQuality.DataQuality.Line4 = 'Line3';
537
+ ExperianDataQuality.DataQuality.Line5 = 'Line4';
538
+ ExperianDataQuality.DataQuality.Line6 = 'Line5';
539
+
540
+ ExperianDataQuality.DataQuality.HtmlTags.Span = 'SPAN';
541
+ ExperianDataQuality.DataQuality.HtmlTags.Div = 'DIV';
542
+ ExperianDataQuality.DataQuality.HtmlTags.ListItem = 'LI';
543
+ ExperianDataQuality.DataQuality.HtmlTags.TableHeader = 'TH';
544
+ ExperianDataQuality.DataQuality.HtmlTags.TableData = 'TD';
545
+ ExperianDataQuality.DataQuality.HtmlTags.TableRow = 'TR';
546
+ ExperianDataQuality.DataQuality.HtmlTags.Select = 'SELECT';
547
+ ExperianDataQuality.DataQuality.HtmlTags.Label = 'LABEL';
548
+ ExperianDataQuality.DataQuality.HtmlTags.Button = 'BUTTON';
549
+ ExperianDataQuality.DataQuality.HtmlTags.Link = 'A';
550
+ ExperianDataQuality.DataQuality.HtmlTags.Option = 'OPTION';
551
+ ExperianDataQuality.DataQuality.HtmlTags.Input = 'INPUT';
552
+
553
+ ExperianDataQuality.DataQuality.Snapshot = {
554
+ 'Line0' : '',
555
+ 'Line1' : '',
556
+ 'Line2' : '',
557
+ 'Line3' : '',
558
+ 'Line4' : '',
559
+ //'DataSet' : '',
560
+ 'Street1' : '',
561
+ 'City' : '',
562
+ 'Postcode' : '',
563
+ 'State' : '',
564
+ 'BuildingNumberOrName' : ''
565
+ };
skin/adminhtml/default/default/ExperianDataQuality/js/json2.js ADDED
@@ -0,0 +1,480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ http://www.JSON.org/json2.js
3
+ 2011-02-23
4
+
5
+ Public Domain.
6
+
7
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8
+
9
+ See http://www.JSON.org/js.html
10
+
11
+
12
+ This code should be minified before deployment.
13
+ See http://javascript.crockford.com/jsmin.html
14
+
15
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16
+ NOT CONTROL.
17
+
18
+
19
+ This file creates a global JSON object containing two methods: stringify
20
+ and parse.
21
+
22
+ JSON.stringify(value, replacer, space)
23
+ value any JavaScript value, usually an object or array.
24
+
25
+ replacer an optional parameter that determines how object
26
+ values are stringified for objects. It can be a
27
+ function or an array of strings.
28
+
29
+ space an optional parameter that specifies the indentation
30
+ of nested structures. If it is omitted, the text will
31
+ be packed without extra whitespace. If it is a number,
32
+ it will specify the number of spaces to indent at each
33
+ level. If it is a string (such as '\t' or '&nbsp;'),
34
+ it contains the characters used to indent at each level.
35
+
36
+ This method produces a JSON text from a JavaScript value.
37
+
38
+ When an object value is found, if the object contains a toJSON
39
+ method, its toJSON method will be called and the result will be
40
+ stringified. A toJSON method does not serialize: it returns the
41
+ value represented by the name/value pair that should be serialized,
42
+ or undefined if nothing should be serialized. The toJSON method
43
+ will be passed the key associated with the value, and this will be
44
+ bound to the value
45
+
46
+ For example, this would serialize Dates as ISO strings.
47
+
48
+ Date.prototype.toJSON = function (key) {
49
+ function f(n) {
50
+ // Format integers to have at least two digits.
51
+ return n < 10 ? '0' + n : n;
52
+ }
53
+
54
+ return this.getUTCFullYear() + '-' +
55
+ f(this.getUTCMonth() + 1) + '-' +
56
+ f(this.getUTCDate()) + 'T' +
57
+ f(this.getUTCHours()) + ':' +
58
+ f(this.getUTCMinutes()) + ':' +
59
+ f(this.getUTCSeconds()) + 'Z';
60
+ };
61
+
62
+ You can provide an optional replacer method. It will be passed the
63
+ key and value of each member, with this bound to the containing
64
+ object. The value that is returned from your method will be
65
+ serialized. If your method returns undefined, then the member will
66
+ be excluded from the serialization.
67
+
68
+ If the replacer parameter is an array of strings, then it will be
69
+ used to select the members to be serialized. It filters the results
70
+ such that only members with keys listed in the replacer array are
71
+ stringified.
72
+
73
+ Values that do not have JSON representations, such as undefined or
74
+ functions, will not be serialized. Such values in objects will be
75
+ dropped; in arrays they will be replaced with null. You can use
76
+ a replacer function to replace those with JSON values.
77
+ JSON.stringify(undefined) returns undefined.
78
+
79
+ The optional space parameter produces a stringification of the
80
+ value that is filled with line breaks and indentation to make it
81
+ easier to read.
82
+
83
+ If the space parameter is a non-empty string, then that string will
84
+ be used for indentation. If the space parameter is a number, then
85
+ the indentation will be that many spaces.
86
+
87
+ Example:
88
+
89
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
90
+ // text is '["e",{"pluribus":"unum"}]'
91
+
92
+
93
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95
+
96
+ text = JSON.stringify([new Date()], function (key, value) {
97
+ return this[key] instanceof Date ?
98
+ 'Date(' + this[key] + ')' : value;
99
+ });
100
+ // text is '["Date(---current time---)"]'
101
+
102
+
103
+ JSON.parse(text, reviver)
104
+ This method parses a JSON text to produce an object or array.
105
+ It can throw a SyntaxError exception.
106
+
107
+ The optional reviver parameter is a function that can filter and
108
+ transform the results. It receives each of the keys and values,
109
+ and its return value is used instead of the original value.
110
+ If it returns what it received, then the structure is not modified.
111
+ If it returns undefined then the member is deleted.
112
+
113
+ Example:
114
+
115
+ // Parse the text. Values that look like ISO date strings will
116
+ // be converted to Date objects.
117
+
118
+ myData = JSON.parse(text, function (key, value) {
119
+ var a;
120
+ if (typeof value === 'string') {
121
+ a =
122
+ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123
+ if (a) {
124
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125
+ +a[5], +a[6]));
126
+ }
127
+ }
128
+ return value;
129
+ });
130
+
131
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132
+ var d;
133
+ if (typeof value === 'string' &&
134
+ value.slice(0, 5) === 'Date(' &&
135
+ value.slice(-1) === ')') {
136
+ d = new Date(value.slice(5, -1));
137
+ if (d) {
138
+ return d;
139
+ }
140
+ }
141
+ return value;
142
+ });
143
+
144
+
145
+ This is a reference implementation. You are free to copy, modify, or
146
+ redistribute.
147
+ */
148
+
149
+ /*jslint evil: true, strict: false, regexp: false */
150
+
151
+ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
155
+ test, toJSON, toString, valueOf
156
+ */
157
+
158
+
159
+ // Create a JSON object only if one does not already exist. We create the
160
+ // methods in a closure to avoid creating global variables.
161
+
162
+ var JSON;
163
+ if (!JSON) {
164
+ JSON = {};
165
+ }
166
+
167
+ (function () {
168
+ "use strict";
169
+
170
+ function f(n) {
171
+ // Format integers to have at least two digits.
172
+ return n < 10 ? '0' + n : n;
173
+ }
174
+
175
+ if (typeof Date.prototype.toJSON !== 'function') {
176
+
177
+ Date.prototype.toJSON = function (key) {
178
+
179
+ return isFinite(this.valueOf()) ?
180
+ this.getUTCFullYear() + '-' +
181
+ f(this.getUTCMonth() + 1) + '-' +
182
+ f(this.getUTCDate()) + 'T' +
183
+ f(this.getUTCHours()) + ':' +
184
+ f(this.getUTCMinutes()) + ':' +
185
+ f(this.getUTCSeconds()) + 'Z' : null;
186
+ };
187
+
188
+ String.prototype.toJSON =
189
+ Number.prototype.toJSON =
190
+ Boolean.prototype.toJSON = function (key) {
191
+ return this.valueOf();
192
+ };
193
+ }
194
+
195
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
196
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
197
+ gap,
198
+ indent,
199
+ meta = { // table of character substitutions
200
+ '\b': '\\b',
201
+ '\t': '\\t',
202
+ '\n': '\\n',
203
+ '\f': '\\f',
204
+ '\r': '\\r',
205
+ '"' : '\\"',
206
+ '\\': '\\\\'
207
+ },
208
+ rep;
209
+
210
+
211
+ function quote(string) {
212
+
213
+ // If the string contains no control characters, no quote characters, and no
214
+ // backslash characters, then we can safely slap some quotes around it.
215
+ // Otherwise we must also replace the offending characters with safe escape
216
+ // sequences.
217
+
218
+ escapable.lastIndex = 0;
219
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220
+ var c = meta[a];
221
+ return typeof c === 'string' ? c :
222
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
223
+ }) + '"' : '"' + string + '"';
224
+ }
225
+
226
+
227
+ function str(key, holder) {
228
+
229
+ // Produce a string from holder[key].
230
+
231
+ var i, // The loop counter.
232
+ k, // The member key.
233
+ v, // The member value.
234
+ length,
235
+ mind = gap,
236
+ partial,
237
+ value = holder[key];
238
+
239
+ // If the value has a toJSON method, call it to obtain a replacement value.
240
+
241
+ if (value && typeof value === 'object' &&
242
+ typeof value.toJSON === 'function') {
243
+ value = value.toJSON(key);
244
+ }
245
+
246
+ // If we were called with a replacer function, then call the replacer to
247
+ // obtain a replacement value.
248
+
249
+ if (typeof rep === 'function') {
250
+ value = rep.call(holder, key, value);
251
+ }
252
+
253
+ // What happens next depends on the value's type.
254
+
255
+ switch (typeof value) {
256
+ case 'string':
257
+ return quote(value);
258
+
259
+ case 'number':
260
+
261
+ // JSON numbers must be finite. Encode non-finite numbers as null.
262
+
263
+ return isFinite(value) ? String(value) : 'null';
264
+
265
+ case 'boolean':
266
+ case 'null':
267
+
268
+ // If the value is a boolean or null, convert it to a string. Note:
269
+ // typeof null does not produce 'null'. The case is included here in
270
+ // the remote chance that this gets fixed someday.
271
+
272
+ return String(value);
273
+
274
+ // If the type is 'object', we might be dealing with an object or an array or
275
+ // null.
276
+
277
+ case 'object':
278
+
279
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
280
+ // so watch out for that case.
281
+
282
+ if (!value) {
283
+ return 'null';
284
+ }
285
+
286
+ // Make an array to hold the partial results of stringifying this object value.
287
+
288
+ gap += indent;
289
+ partial = [];
290
+
291
+ // Is the value an array?
292
+
293
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
294
+
295
+ // The value is an array. Stringify every element. Use null as a placeholder
296
+ // for non-JSON values.
297
+
298
+ length = value.length;
299
+ for (i = 0; i < length; i += 1) {
300
+ partial[i] = str(i, value) || 'null';
301
+ }
302
+
303
+ // Join all of the elements together, separated with commas, and wrap them in
304
+ // brackets.
305
+
306
+ v = partial.length === 0 ? '[]' : gap ?
307
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
308
+ '[' + partial.join(',') + ']';
309
+ gap = mind;
310
+ return v;
311
+ }
312
+
313
+ // If the replacer is an array, use it to select the members to be stringified.
314
+
315
+ if (rep && typeof rep === 'object') {
316
+ length = rep.length;
317
+ for (i = 0; i < length; i += 1) {
318
+ if (typeof rep[i] === 'string') {
319
+ k = rep[i];
320
+ v = str(k, value);
321
+ if (v) {
322
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
323
+ }
324
+ }
325
+ }
326
+ } else {
327
+
328
+ // Otherwise, iterate through all of the keys in the object.
329
+
330
+ for (k in value) {
331
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
332
+ v = str(k, value);
333
+ if (v) {
334
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ // Join all of the member texts together, separated with commas,
341
+ // and wrap them in braces.
342
+
343
+ v = partial.length === 0 ? '{}' : gap ?
344
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
345
+ '{' + partial.join(',') + '}';
346
+ gap = mind;
347
+ return v;
348
+ }
349
+ }
350
+
351
+ // If the JSON object does not yet have a stringify method, give it one.
352
+
353
+ if (typeof JSON.stringify !== 'function') {
354
+ JSON.stringify = function (value, replacer, space) {
355
+
356
+ // The stringify method takes a value and an optional replacer, and an optional
357
+ // space parameter, and returns a JSON text. The replacer can be a function
358
+ // that can replace values, or an array of strings that will select the keys.
359
+ // A default replacer method can be provided. Use of the space parameter can
360
+ // produce text that is more easily readable.
361
+
362
+ var i;
363
+ gap = '';
364
+ indent = '';
365
+
366
+ // If the space parameter is a number, make an indent string containing that
367
+ // many spaces.
368
+
369
+ if (typeof space === 'number') {
370
+ for (i = 0; i < space; i += 1) {
371
+ indent += ' ';
372
+ }
373
+
374
+ // If the space parameter is a string, it will be used as the indent string.
375
+
376
+ } else if (typeof space === 'string') {
377
+ indent = space;
378
+ }
379
+
380
+ // If there is a replacer, it must be a function or an array.
381
+ // Otherwise, throw an error.
382
+
383
+ rep = replacer;
384
+ if (replacer && typeof replacer !== 'function' &&
385
+ (typeof replacer !== 'object' ||
386
+ typeof replacer.length !== 'number')) {
387
+ throw new Error('JSON.stringify');
388
+ }
389
+
390
+ // Make a fake root object containing our value under the key of ''.
391
+ // Return the result of stringifying the value.
392
+
393
+ return str('', {'': value});
394
+ };
395
+ }
396
+
397
+
398
+ // If the JSON object does not yet have a parse method, give it one.
399
+
400
+ if (typeof JSON.parse !== 'function') {
401
+ JSON.parse = function (text, reviver) {
402
+
403
+ // The parse method takes a text and an optional reviver function, and returns
404
+ // a JavaScript value if the text is a valid JSON text.
405
+
406
+ var j;
407
+
408
+ function walk(holder, key) {
409
+
410
+ // The walk method is used to recursively walk the resulting structure so
411
+ // that modifications can be made.
412
+
413
+ var k, v, value = holder[key];
414
+ if (value && typeof value === 'object') {
415
+ for (k in value) {
416
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
417
+ v = walk(value, k);
418
+ if (v !== undefined) {
419
+ value[k] = v;
420
+ } else {
421
+ delete value[k];
422
+ }
423
+ }
424
+ }
425
+ }
426
+ return reviver.call(holder, key, value);
427
+ }
428
+
429
+
430
+ // Parsing happens in four stages. In the first stage, we replace certain
431
+ // Unicode characters with escape sequences. JavaScript handles many characters
432
+ // incorrectly, either silently deleting them, or treating them as line endings.
433
+
434
+ text = String(text);
435
+ cx.lastIndex = 0;
436
+ if (cx.test(text)) {
437
+ text = text.replace(cx, function (a) {
438
+ return '\\u' +
439
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
440
+ });
441
+ }
442
+
443
+ // In the second stage, we run the text against regular expressions that look
444
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
445
+ // because they can cause invocation, and '=' because it can cause mutation.
446
+ // But just to be safe, we want to reject all unexpected forms.
447
+
448
+ // We split the second stage into 4 regexp operations in order to work around
449
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
450
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
451
+ // replace all simple value tokens with ']' characters. Third, we delete all
452
+ // open brackets that follow a colon or comma or that begin the text. Finally,
453
+ // we look to see that the remaining characters are only whitespace or ']' or
454
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
455
+
456
+ if (/^[\],:{}\s]*$/
457
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
458
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
459
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
460
+
461
+ // In the third stage we use the eval function to compile the text into a
462
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
463
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
464
+ // in parens to eliminate the ambiguity.
465
+
466
+ j = eval('(' + text + ')');
467
+
468
+ // In the optional fourth stage, we recursively walk the new structure, passing
469
+ // each name/value pair to a reviver function for possible transformation.
470
+
471
+ return typeof reviver === 'function' ?
472
+ walk({'': j}, '') : j;
473
+ }
474
+
475
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
476
+
477
+ throw new SyntaxError('JSON.parse');
478
+ };
479
+ }
480
+ }());
skin/adminhtml/default/default/ExperianDataQuality/js/system.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var ExperianDataQuality = ExperianDataQuality || {};
2
+ ExperianDataQuality.system = ExperianDataQuality.system || {};
3
+
4
+ ExperianDataQuality.system.isString = function isString(value) { return typeof value === "string"; };
5
+ ExperianDataQuality.system.isUndefined = function isUndefined(value) { return typeof(value) === "undefined"; };
6
+ ExperianDataQuality.system.isNull = function isNull(value) { return ExperianDataQuality.system.isUndefined(value) || value === null; };
7
+ ExperianDataQuality.system.isNullOrEmpty = function isNullOrEmpty(str) { return ExperianDataQuality.system.isNull(str) || str === ""; };
8
+ ExperianDataQuality.system.isFunction = function isFunction(obj) { return !ExperianDataQuality.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Function]'; };
9
+ ExperianDataQuality.system.isArray = function isArray(obj) { return !ExperianDataQuality.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Array]'; };
10
+ ExperianDataQuality.system.logError = function logError(obj) {
11
+ if (window.console) {
12
+ window.console.log(obj);
13
+ } else { //IE does not have a logger.
14
+ //alert(obj);
15
+ };
16
+ };
17
+
18
+ ExperianDataQuality.system.containsInArray = function containsInArray(needle, haystack) {
19
+ if (haystack.indexOf(needle) !== -1) {
20
+ return true;
21
+ }
22
+ return false;
23
+ };
24
+
25
+ ExperianDataQuality.system.contains = function contains(needle, haystack) {
26
+ if (typeof haystack[needle] === 'undefined') {
27
+ return false;
28
+ }
29
+ return true;
30
+ };
31
+
32
+ ExperianDataQuality.system.getElementValue = function getElementValue(htmlElementId) {
33
+ var htmlElement = this.getElementById(htmlElementId);
34
+ if (this.isNull(htmlElement)) {
35
+ return undefined;
36
+ }
37
+
38
+ return htmlElement.value;
39
+ };
40
+
41
+ ExperianDataQuality.system.setElementValue = function setElementValue(htmlElementId, value) {
42
+ var htmlElement = this.getElementById(htmlElementId);
43
+ if (this.isNull(htmlElement)) {
44
+ return;
45
+ }
46
+
47
+ if (htmlElement.tagName === "LABEL") {
48
+ htmlElement.innerHTML = value;
49
+ } else {
50
+ htmlElement.value = value;
51
+ }
52
+ };
53
+
54
+ ExperianDataQuality.system.getElementById = function getElementById(selector) {
55
+ return document.getElementById(selector);
56
+ };
57
+
58
+ ExperianDataQuality.system.getElementLabelById = function getElementLabelById(htmlElementId) {
59
+ var labels = document.getElementsByTagName('Label');
60
+
61
+ for (var i = 0, max = labels.length; i < max; i++) {
62
+ if(!this.isNull(labels[i].attributes['for'])) {
63
+ if(labels[i].attributes['for'].value === htmlElementId) {
64
+ return labels[i];
65
+ }
66
+ }
67
+ }
68
+
69
+ return undefined;
70
+ };
71
+
72
+ ExperianDataQuality.system.toBoolean = function toBoolean(value) {
73
+ if (value.toString().toUpperCase() === 'TRUE' || value.toString() === '1') {
74
+ return true;
75
+ }
76
+ return false;
77
+ };
78
+
79
+ ExperianDataQuality.system.beginsWith = function beginsWith(needle, haystack) {
80
+ return (haystack.substr(0, needle.length) === needle);
81
+ };
82
+
83
+ ExperianDataQuality.system.endsWith = function endsWith(needle, haystack) {
84
+ return haystack.indexOf(needle, haystack.length - needle.length) !== -1;
85
+ };
86
+
87
+ ExperianDataQuality.system.removeSpecialCharacters = function removeSpecialCharacters(value) {
88
+ return value.replace(/[^\d.]/g, "");
89
+ };
90
+
91
+ ExperianDataQuality.system.inherit = (function () {
92
+ var F = function (){};
93
+ return function (C, P) {
94
+ F.prototype = P.prototype;
95
+ C.prototype = new F();
96
+ C.uber = P.prototype;
97
+ C.prototype.constructor = C;
98
+ };
99
+ }());
100
+
101
+ if (Array && !Array.indexOf){
102
+ Array.prototype.indexOf = function (elt /*, from*/) {
103
+ var len = this.length;
104
+
105
+ var from = Number(arguments[1]) || 0;
106
+ from = (from < 0)? Math.ceil(from) : Math.floor(from);
107
+ if (from < 0) { from += len; }
108
+ for (; from < len; from++) {
109
+ if (from in this && this[from] === elt) { return from;}
110
+ }
111
+ return -1;
112
+ };
113
+ };
114
+
115
+ if(typeof String.prototype.trim !== 'function') {
116
+ String.prototype.trim = function() {
117
+ return this.replace(/^\s+|\s+$/g, '');
118
+ };
119
+ };
skin/adminhtml/default/default/edq/images/opc-ajax-loader.gif ADDED
Binary file
skin/adminhtml/default/default/edq/js/edqClient.js ADDED
@@ -0,0 +1,526 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var EDQ = EDQ || {};
2
+ EDQ.DataQuality = EDQ.DataQuality || {};
3
+
4
+ //Configuration_Start
5
+ EDQ.DataQuality.Configuration = function Configuration(outputMappings, inputMappings, type) {
6
+ var dq = EDQ.DataQuality;
7
+
8
+ this._inputMappings = inputMappings || [];
9
+ this._outputMappings = outputMappings || [];
10
+ this.type = type;
11
+ };
12
+
13
+ EDQ.DataQuality.Configuration.prototype.addOutputMapping = function addOutputMapping(htmlFieldId, edqFieldName) {
14
+ var dq = EDQ.DataQuality;
15
+ var sys = EDQ.system;
16
+
17
+ var mapping = this.getOutputMappingByElementId(htmlFieldId);
18
+ if (!sys.isNull(mapping)) {
19
+ mapping.addEDQFieldName(edqFieldName);
20
+ } else {
21
+ mapping = new dq.OutputMapping(htmlFieldId, edqFieldName);
22
+ this._outputMappings.push(mapping);
23
+ };
24
+ };
25
+
26
+ EDQ.DataQuality.Configuration.prototype.getOutputMappingByElementId = function getOutputMappingByElementId(htmlFieldId) {
27
+ var sys = EDQ.system;
28
+
29
+ if (sys.isNull(this._outputMappings) || this._outputMappings.length === 0) {
30
+ return null;
31
+ }
32
+
33
+ for (var i = 0; i < this._outputMappings.length; i++) {
34
+ if (this._outputMappings[i].htmlFieldId === htmlFieldId) {
35
+ return this._outputMappings[i];
36
+ }
37
+ }
38
+ };
39
+
40
+ EDQ.DataQuality.Configuration.prototype._getOutputMappingByEdqFieldName = function _getOutputMappingByEdqFieldName(edqFieldName) {
41
+ var sys = EDQ.system;
42
+
43
+ if (sys.isNull(this._outputMappings) || this._outputMappings.length === 0) {
44
+ return null;
45
+ }
46
+
47
+ for (var i = 0; i < this._outputMappings.length; i++) {
48
+ for (var j = 0; j < this._outputMappings[i].edqFieldNames.length; j++) {
49
+ if (this._outputMappings[i].edqFieldNames[j] === edqFieldName) {
50
+ return this._outputMappings[i];
51
+ }
52
+ }
53
+ }
54
+
55
+ return null;
56
+ };
57
+
58
+ EDQ.DataQuality.Configuration.prototype.addInputMapping = function addInputMapping(edqFieldName, htmlFieldId) {
59
+ var dq = EDQ.DataQuality;
60
+ var sys = EDQ.system;
61
+
62
+ var mapping = this.getInputMappingByEdqFieldName(edqFieldName);
63
+ if (!sys.isNull(mapping)) {
64
+ mapping.addHtmlFieldId(htmlFieldId);
65
+ } else {
66
+ mapping = new dq.InputMapping(edqFieldName, htmlFieldId);
67
+ this._inputMappings.push(mapping);
68
+ };
69
+ };
70
+
71
+ EDQ.DataQuality.Configuration.prototype.getInputMappingByEdqFieldName = function getInputMappingByEdqFieldName(edqFieldName) {
72
+ var sys = EDQ.system;
73
+
74
+ if (sys.isNull(this._inputMappings) || this._inputMappings.length === 0) {
75
+ return null;
76
+ }
77
+
78
+ for (var i = 0; i < this._inputMappings.length; i++) {
79
+ if (this._inputMappings[i].edqFieldName === edqFieldName) {
80
+ return this._inputMappings[i];
81
+ }
82
+ }
83
+ };
84
+ //Configuration_End
85
+
86
+ //Mapping_Start
87
+ EDQ.DataQuality.OutputMapping = function OutputMapping(htmlFieldId, edqFieldName) {
88
+ this.htmlFieldId = htmlFieldId;
89
+ this.edqFieldNames = [];
90
+ this.addEDQFieldName(edqFieldName);
91
+ };
92
+
93
+ EDQ.DataQuality.OutputMapping.prototype.addEDQFieldName = function addEDQFieldName(edqFieldName) {
94
+ var sys = EDQ.system;
95
+
96
+ if (sys.isNull(edqFieldName) || typeof edqFieldName !== "string") { throw "Invalid edqFieldName value: " + edqFieldName; }
97
+
98
+ this.edqFieldNames.push(edqFieldName);
99
+ };
100
+
101
+ EDQ.DataQuality.InputMapping = function InputMapping(edqFieldName, htmlFieldId) {
102
+ this.edqFieldName = edqFieldName;
103
+ this.htmlFieldIds = [];
104
+ this.addHtmlFieldId(htmlFieldId);
105
+ };
106
+
107
+ EDQ.DataQuality.InputMapping.prototype.addHtmlFieldId = function addHtmlFieldId(htmlFieldId) {
108
+ var sys = EDQ.system;
109
+
110
+ if (sys.isNull(htmlFieldId) || typeof htmlFieldId !== "string") { throw "Invalid htmlFieldId value: " + htmlFieldId; }
111
+
112
+ this.htmlFieldIds.push(htmlFieldId);
113
+ };
114
+ //Mapping_End
115
+
116
+ //Client_Start
117
+ EDQ.DataQuality.Client = function Client(configurations, settings) {
118
+ var sys = EDQ.system;
119
+ var dq = EDQ.DataQuality;
120
+
121
+ settings = settings || {};
122
+ this.phoneServiceUrl = settings.phoneUrl || '';
123
+ this.emailServiceUrl = settings.emailUrl || '';
124
+ this.serviceUrl = settings.url || '';
125
+ this.emailValidationKey = settings.emailValidationKey || '';
126
+ this.phoneValidationKey = settings.phoneValidationKey || '';
127
+ this.fadeoutValidationMessageTimeout = settings.fadeoutValidationMessageTimeout || 1000;
128
+ this.defaultCountry = settings.defaultCountry || 'USA';
129
+ this.delimiter = settings.delimiter || ', ';
130
+ this._configurations = configurations;
131
+ this._token = settings.token || '';
132
+ };
133
+ EDQ.DataQuality.Client.prototype.initialize = function initialize() {
134
+ var sys = EDQ.system;
135
+
136
+ if (sys.isNull(this._configurations)) { return; }
137
+
138
+ for (var i = 0; i < this._configurations.length; i++) {
139
+ this._initializeForConfiguration(this._configurations[i]);
140
+ }
141
+ };
142
+
143
+ EDQ.DataQuality.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) {
144
+ var dq = EDQ.DataQuality;
145
+ var sys = EDQ.system;
146
+
147
+ var client = this;
148
+ var elementIds = this._getElementIdsWhichInvokeValidation(configuration);
149
+
150
+ for (var i = 0; i < elementIds.length; i++) {
151
+ var element = sys.getById(elementIds[i]);
152
+
153
+ if (sys.isNull(element)) { continue; };
154
+ if (element.edq_eventsAttached === true) { continue; };
155
+
156
+ element.oldValue = element.value;
157
+
158
+ if (element.tagName === "SELECT") {
159
+ var previousOnChange = element.onchange;
160
+
161
+ element.onchange = function (event) {
162
+ if (sys.isFunction(previousOnChange)) {
163
+ previousOnChange.apply(this, [event]);
164
+ };
165
+
166
+ client._validateField(configuration, element, function () { element.oldValue = element.value; });
167
+ };
168
+ } else {
169
+ var previousOnBlur = element.onblur;
170
+
171
+ element.onblur = function (event) {
172
+ if (sys.isFunction(previousOnBlur)) {
173
+ previousOnBlur.apply(this, [event]);
174
+ };
175
+
176
+ if(element.oldValue !== element.value) {
177
+ client._validateField(configuration, element, function () { element.oldValue = element.value; });
178
+ }
179
+ };
180
+ }
181
+
182
+ element.edq_eventsAttached = true;
183
+ };
184
+ };
185
+
186
+ EDQ.DataQuality.Client.prototype._getElementIdsWhichInvokeValidation = function _getElementIdsWhichInvokeValidation(configuration) {
187
+ var sys = EDQ.system;
188
+ var dq = EDQ.DataQuality;
189
+
190
+ var elementIds = [];
191
+
192
+ if (!sys.isNull(configuration._inputMappings) && configuration._inputMappings.length > 0) {
193
+ for (var i = 0; i < configuration._inputMappings.length; i++) {
194
+ for (var j = 0; j < configuration._inputMappings[i].htmlFieldIds.length; j++) {
195
+ elementIds.push(configuration._inputMappings[i].htmlFieldIds[j]);
196
+ }
197
+ }
198
+ } else if (!sys.isNull(configuration._outputMappings) && configuration._outputMappings.length > 0) {
199
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
200
+ elementIds.push(configuration._outputMappings[i].htmlFieldId);
201
+ }
202
+ }
203
+
204
+ return elementIds;
205
+ };
206
+
207
+ EDQ.DataQuality.Client.prototype._validateField = function _validateField(configuration, element, afterValuesSetCallback) {
208
+ var sys = EDQ.system;
209
+ var dq = EDQ.DataQuality;
210
+ var client = dq.Client;
211
+
212
+ var edqFieldName;
213
+ var serviceUrl = '';;
214
+ switch (configuration.type) {
215
+ case 1:
216
+ edqFieldName = dq.Email;
217
+ serviceUrl = this.emailServiceUrl;
218
+ break;
219
+ case 2:
220
+ edqFieldName = dq.Phone;
221
+ serviceUrl = this.phoneServiceUrl;
222
+ break;
223
+ default:
224
+ sys.logError('Unsupported configuration type: ' + configuration.type);
225
+ }
226
+ var sessionToken = this._token;
227
+ var htmlFieldIds = this._getFieldsFromMapping(edqFieldName, configuration);
228
+ var value = '';
229
+ for (var i = 0; i < htmlFieldIds.length; i++) {
230
+ var element = client.getField(htmlFieldIds[i]);
231
+ if (sys.isNull(element)) {
232
+ continue;
233
+ }
234
+
235
+ value += element.value;
236
+ }
237
+ if(sys.isNullOrEmpty(value)) { return; }
238
+
239
+ var countryCode = '';
240
+ var phoneCountryExists = false;
241
+ if (configuration.type === dq.ConfigurationType.Phone) {
242
+ for (var i = 0; i < configuration._inputMappings.length; i++) {
243
+ var inputMapping = configuration._inputMappings[i];
244
+ if(inputMapping.edqFieldName === dq.PhoneCountry) {
245
+ phoneCountryExists = true;
246
+ }
247
+ }
248
+
249
+ if(phoneCountryExists) {
250
+ var countryElements = this._getFieldsFromMapping(dq.PhoneCountry, configuration);
251
+ var country = client.getFieldValue(countryElements[0]);
252
+ countryCode = country;
253
+ } else {
254
+ countryCode = this.defaultCountry;
255
+ }
256
+ }
257
+
258
+ client._setValidationMessageAndLoader(configuration, 'show', '');
259
+
260
+ var postParameters = {};
261
+ if(configuration.type === 1) {
262
+ postParameters = { 'email-address': element.value, 'session-security-token' : sessionToken };
263
+ } else {
264
+ postParameters = { 'telephone-number': element.value, 'telephone-area-code': countryCode, 'session-security-token' : sessionToken };
265
+ }
266
+
267
+ var client = this;
268
+ var request = new Ajax.Request(serviceUrl,
269
+ {
270
+ method: 'post',
271
+ onSuccess: function(transport) {
272
+ client.processResult(transport, configuration, countryCode);
273
+ if(!sys.isNull(afterValuesSetCallback)) {
274
+ afterValuesSetCallback();
275
+ }
276
+ dq.Client._twistLoader(configuration, '');
277
+ },
278
+ onFailure: function(transport) {
279
+ client.processError(transport.xhr, transport.statusText, transport.error, configuration);
280
+ if(!sys.isNull(afterValuesSetCallback)) {
281
+ afterValuesSetCallback();
282
+ }
283
+ },
284
+ parameters: postParameters
285
+ }
286
+ );
287
+ };
288
+
289
+ EDQ.DataQuality.Client.prototype._getFieldsFromMapping = function _getFieldsFromMapping(edqFieldName, configuration) {
290
+ var sys = EDQ.system;
291
+
292
+ var fields = [];
293
+ var fields = configuration.getInputMappingByEdqFieldName(edqFieldName).htmlFieldIds;
294
+
295
+ if (!sys.isNull(fields)) {
296
+ return fields;
297
+ } else {
298
+ fields.push(configuration._getOutputMappingByEdqFieldName(edqFieldName).htmlFieldId);
299
+ }
300
+
301
+ return fields;
302
+ };
303
+
304
+ EDQ.DataQuality.Client.prototype.processResult = function processResult(response, configuration, countryCode) {
305
+ var dq = EDQ.DataQuality;
306
+
307
+ var responseInJson = JSON.parse(response.responseText);
308
+ var certainty = responseInJson.Certainty;
309
+
310
+ switch (configuration.type) {
311
+ case 1:
312
+ responseInJson.ValidationMessageForLabel = (dq.EmailResultCodesAndDescriptions[certainty.toUpperCase()]
313
+ ? dq.EmailResultCodesAndDescriptions[certainty.toUpperCase()]
314
+ : certainty);
315
+ if(responseInJson.Corrections) {
316
+ if(certainty.toUpperCase() !== 'UNKNOWN' && certainty.toUpperCase() !== 'VERIFIED' ) {
317
+ responseInJson.Corrections = '(Suggested: ' + responseInJson.Corrections.join(' ') + ')';
318
+ }
319
+ else {
320
+ responseInJson.Corrections = '';
321
+ }
322
+ }
323
+ break;
324
+ case 2:
325
+ responseInJson.ValidationMessageForLabel = (dq.PhoneResultCodesAndDescriptions[certainty.toUpperCase()]
326
+ ? dq.PhoneResultCodesAndDescriptions[certainty.toUpperCase()]
327
+ : certainty);
328
+ break;
329
+ }
330
+
331
+ responseInJson.ValidationMessage = responseInJson.ValidationMessageForLabel;
332
+
333
+ this.setValues(responseInJson, configuration, countryCode);
334
+ };
335
+
336
+ EDQ.DataQuality.Client.prototype.processError = function processError(xhr, statusText, error, configuration) {
337
+ var dq = EDQ.DataQuality;
338
+ var client = dq.Client;
339
+ var sys = EDQ.system;
340
+
341
+ sys.logError(statusText);
342
+ sys.logError(error);
343
+
344
+ client._setValidationMessageAndLoader(configuration, '', 'Unable to validate.');
345
+ };
346
+
347
+ EDQ.DataQuality.Client._setValidationMessageAndLoader = function _setValidationMessageAndLoader(configuration, loaderDisplayStatus, responseText) {
348
+ var dq = EDQ.DataQuality;
349
+ var client = dq.Client;
350
+ var sys = EDQ.system;
351
+
352
+ var suggestionMessageLabelMapping = configuration._getOutputMappingByEdqFieldName(dq.CorrectionsForLabel);
353
+ var validationMessageMapping = configuration._getOutputMappingByEdqFieldName(dq.ValidationMessageForLabel);
354
+
355
+ if (!sys.isNullOrEmpty(validationMessageMapping)) {
356
+ client._setValidationMessage(validationMessageMapping.htmlFieldId, responseText);
357
+
358
+ if(!sys.isNullOrEmpty(suggestionMessageLabelMapping)) {
359
+ client._setValidationMessage(suggestionMessageLabelMapping.htmlFieldId, '');
360
+ }
361
+
362
+ client._twistLoader(configuration, loaderDisplayStatus);
363
+ }
364
+ };
365
+
366
+ EDQ.DataQuality.Client.prototype.setValues = function setValues(result, configuration, countryCode) {
367
+ var dq = EDQ.DataQuality;
368
+ var sys = EDQ.system;
369
+
370
+ if (sys.isNull(result[dq.ErrorMessage])) {
371
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
372
+ this._setValue(configuration._outputMappings[i], result, configuration.type, countryCode);
373
+ }
374
+ }
375
+ };
376
+
377
+ EDQ.DataQuality.Client.prototype._setValue = function _setValue(mapping, result, type, countryCode) {
378
+ var dq = EDQ.DataQuality;
379
+ var sys = EDQ.system;
380
+ var client = dq.Client;
381
+
382
+ var val = '';
383
+ var edqFieldName = '';
384
+ for (var j = 0; j < mapping.edqFieldNames.length; j++) {
385
+ edqFieldName = mapping.edqFieldNames[j];
386
+ var fieldValue = result[edqFieldName];
387
+
388
+ if (sys.isNullOrEmpty(fieldValue)) {
389
+ continue;
390
+ };
391
+
392
+ if (val.length > 0) {
393
+ val += this.delimiter + ' ';
394
+ };
395
+
396
+ val += fieldValue;
397
+ }
398
+
399
+ if(edqFieldName === dq.ValidationMessageForLabel || edqFieldName === dq.CorrectionsForLabel)
400
+ {
401
+ client._setValidationMessage(mapping.htmlFieldId, result[edqFieldName], result.Certainty, type);
402
+ }
403
+ else
404
+ {
405
+ client.setFieldValue(mapping.htmlFieldId, val);
406
+ }
407
+ };
408
+
409
+ EDQ.DataQuality.Client._setValidationMessage = function _setValidationMessage(textId, text, certainty, type) {
410
+ var sys = EDQ.system;
411
+ var client = EDQ.DataQuality.Client;
412
+
413
+ var validationMessageElement = client.getField(textId);
414
+
415
+ if (!sys.isNull(validationMessageElement)) {
416
+ if(validationMessageElement.tagName === "INPUT") {
417
+ validationMessageElement.value = text;
418
+ } else {
419
+ validationMessageElement.innerHTML = text;
420
+
421
+ validationMessageElement.style.display = sys.isNullOrEmpty(text) ? 'none' : 'inline';
422
+ if(certainty !== undefined && type !== undefined) {
423
+ switch (type) {
424
+ case 1:
425
+ validationMessageElement.style.color = certainty.toUpperCase() === 'VERIFIED' || certainty.toUpperCase() === 'UNKNOWN'
426
+ ? 'rgb(105, 153, 53)'
427
+ : '#D40707';
428
+ break;
429
+ case 2:
430
+ validationMessageElement.style.color = certainty.toUpperCase() === 'UNVERIFIED' || certainty.toUpperCase() === "YOUR REQUEST CANNOT BE COMPLETED. YOUR TOKEN IS EXPIRED"
431
+ ? '#D40707'
432
+ : 'rgb(105, 153, 53)';
433
+ break;
434
+ }
435
+ }
436
+ }
437
+ }
438
+ };
439
+
440
+ EDQ.DataQuality.Client.setFieldValue = function setFieldValue(htmlFieldId, value) {
441
+ var sys = EDQ.system;
442
+ var client = EDQ.DataQuality.Client;
443
+
444
+ var field = client.getField(htmlFieldId);
445
+
446
+ if (sys.isNull(field)) {
447
+ return;
448
+ }
449
+
450
+ field.value = value;
451
+ };
452
+
453
+ EDQ.DataQuality.Client.getFieldValue = function getFieldValue(htmlFieldId) {
454
+ var client = EDQ.DataQuality.Client;
455
+ var sys = EDQ.system;
456
+
457
+ var field = client.getField(htmlFieldId);
458
+ if (sys.isNull(field)) {
459
+ return undefined;
460
+ }
461
+
462
+ return field.value;
463
+ };
464
+
465
+ EDQ.DataQuality.Client.getField = function getField(htmlFieldId) {
466
+ return document.getElementById(htmlFieldId);
467
+ };
468
+
469
+ EDQ.DataQuality.Client._twistLoader = function _twistLoader(configuration, displayStatus) {
470
+ var dq = EDQ.DataQuality;
471
+ var sys = EDQ.system;
472
+ var client = EDQ.DataQuality.Client;
473
+
474
+
475
+ var loaderMapping = configuration._getOutputMappingByEdqFieldName(dq.Loader);
476
+
477
+ if(loaderMapping === undefined) {
478
+ return;
479
+ }
480
+
481
+ var loeaderElement = client.getField(loaderMapping.htmlFieldId);
482
+
483
+ if (!sys.isNull(loeaderElement)) {
484
+ loeaderElement.style.display = displayStatus === 'show' ? 'inline' : 'none' ;
485
+ }
486
+ };
487
+ //Client_End
488
+
489
+ EDQ.DataQuality.ConfigurationType = { Email: 1, Phone: 2 };
490
+
491
+ EDQ.DataQuality.Phone = 'Number';
492
+ EDQ.DataQuality.AreaCode = 'AreaCode';
493
+ EDQ.DataQuality.Email = 'Email';
494
+ EDQ.DataQuality.Message = 'Message';
495
+ EDQ.DataQuality.Certainty = 'Certainty';
496
+ EDQ.DataQuality.ValidationMessageForLabel = 'ValidationMessageForLabel';
497
+ EDQ.DataQuality.ValidationMessage = 'ValidationMessage';
498
+ EDQ.DataQuality.Loader = 'Loader';
499
+ EDQ.DataQuality.ErrorMessage = 'ErrorMessage';
500
+ EDQ.DataQuality.ValidationStatusVerified = 'Verified';
501
+ EDQ.DataQuality.ValidationStatusNotVerified = 'Not verified';
502
+ EDQ.DataQuality.ValidationStatus = 'ValidationStatus';
503
+ EDQ.DataQuality.Country = 'Country';
504
+ EDQ.DataQuality.PhoneCountry = 'PhoneCountry';
505
+ EDQ.DataQuality.Suggested = 'Suggested';
506
+ EDQ.DataQuality.CorrectionsForLabel = 'Corrections';
507
+ EDQ.DataQuality.ResultCode = 'ResultCode';
508
+ EDQ.DataQuality.PhoneType = 'PhoneType';
509
+
510
+ EDQ.DataQuality.PhoneResultCodesAndDescriptions = {
511
+ 'VERIFIED' : 'Verified',
512
+ 'UNVERIFIED' : 'Could not be Verified',
513
+ 'UNKNOWN' : 'Verified',
514
+ 'ABSENT' : 'Verified',
515
+ 'TELESERVICE NOT PROVISIONED' : 'Verified',
516
+ 'CALL BARRED' : 'Verified'
517
+ };
518
+
519
+ EDQ.DataQuality.EmailResultCodesAndDescriptions = {
520
+ 'VERIFIED' : 'Email address validated!',
521
+ 'UNDELIVERABLE' : 'Sorry, username does not exist, or mailbox is suspended or disabled. To proceed, please provide a valid e-mail address.',
522
+ 'UNREACHABLE' : 'Sorry, email domain could not be reached or verified. To proceed, please provide a valid e-mail address.',
523
+ 'ILLEGITIMATE' : 'Email could not be verified. To proceed, please provide a valid e-mail address.',
524
+ 'DISPOSABLE' : 'Sorry, email is suspected as disposable. To proceed, please provide a valid e-mail address.',
525
+ 'UNKNOWN' : 'Email address validated!'
526
+ };
skin/adminhtml/default/default/edq/js/json2.js ADDED
@@ -0,0 +1,480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ http://www.JSON.org/json2.js
3
+ 2011-02-23
4
+
5
+ Public Domain.
6
+
7
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8
+
9
+ See http://www.JSON.org/js.html
10
+
11
+
12
+ This code should be minified before deployment.
13
+ See http://javascript.crockford.com/jsmin.html
14
+
15
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16
+ NOT CONTROL.
17
+
18
+
19
+ This file creates a global JSON object containing two methods: stringify
20
+ and parse.
21
+
22
+ JSON.stringify(value, replacer, space)
23
+ value any JavaScript value, usually an object or array.
24
+
25
+ replacer an optional parameter that determines how object
26
+ values are stringified for objects. It can be a
27
+ function or an array of strings.
28
+
29
+ space an optional parameter that specifies the indentation
30
+ of nested structures. If it is omitted, the text will
31
+ be packed without extra whitespace. If it is a number,
32
+ it will specify the number of spaces to indent at each
33
+ level. If it is a string (such as '\t' or '&nbsp;'),
34
+ it contains the characters used to indent at each level.
35
+
36
+ This method produces a JSON text from a JavaScript value.
37
+
38
+ When an object value is found, if the object contains a toJSON
39
+ method, its toJSON method will be called and the result will be
40
+ stringified. A toJSON method does not serialize: it returns the
41
+ value represented by the name/value pair that should be serialized,
42
+ or undefined if nothing should be serialized. The toJSON method
43
+ will be passed the key associated with the value, and this will be
44
+ bound to the value
45
+
46
+ For example, this would serialize Dates as ISO strings.
47
+
48
+ Date.prototype.toJSON = function (key) {
49
+ function f(n) {
50
+ // Format integers to have at least two digits.
51
+ return n < 10 ? '0' + n : n;
52
+ }
53
+
54
+ return this.getUTCFullYear() + '-' +
55
+ f(this.getUTCMonth() + 1) + '-' +
56
+ f(this.getUTCDate()) + 'T' +
57
+ f(this.getUTCHours()) + ':' +
58
+ f(this.getUTCMinutes()) + ':' +
59
+ f(this.getUTCSeconds()) + 'Z';
60
+ };
61
+
62
+ You can provide an optional replacer method. It will be passed the
63
+ key and value of each member, with this bound to the containing
64
+ object. The value that is returned from your method will be
65
+ serialized. If your method returns undefined, then the member will
66
+ be excluded from the serialization.
67
+
68
+ If the replacer parameter is an array of strings, then it will be
69
+ used to select the members to be serialized. It filters the results
70
+ such that only members with keys listed in the replacer array are
71
+ stringified.
72
+
73
+ Values that do not have JSON representations, such as undefined or
74
+ functions, will not be serialized. Such values in objects will be
75
+ dropped; in arrays they will be replaced with null. You can use
76
+ a replacer function to replace those with JSON values.
77
+ JSON.stringify(undefined) returns undefined.
78
+
79
+ The optional space parameter produces a stringification of the
80
+ value that is filled with line breaks and indentation to make it
81
+ easier to read.
82
+
83
+ If the space parameter is a non-empty string, then that string will
84
+ be used for indentation. If the space parameter is a number, then
85
+ the indentation will be that many spaces.
86
+
87
+ Example:
88
+
89
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
90
+ // text is '["e",{"pluribus":"unum"}]'
91
+
92
+
93
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95
+
96
+ text = JSON.stringify([new Date()], function (key, value) {
97
+ return this[key] instanceof Date ?
98
+ 'Date(' + this[key] + ')' : value;
99
+ });
100
+ // text is '["Date(---current time---)"]'
101
+
102
+
103
+ JSON.parse(text, reviver)
104
+ This method parses a JSON text to produce an object or array.
105
+ It can throw a SyntaxError exception.
106
+
107
+ The optional reviver parameter is a function that can filter and
108
+ transform the results. It receives each of the keys and values,
109
+ and its return value is used instead of the original value.
110
+ If it returns what it received, then the structure is not modified.
111
+ If it returns undefined then the member is deleted.
112
+
113
+ Example:
114
+
115
+ // Parse the text. Values that look like ISO date strings will
116
+ // be converted to Date objects.
117
+
118
+ myData = JSON.parse(text, function (key, value) {
119
+ var a;
120
+ if (typeof value === 'string') {
121
+ a =
122
+ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123
+ if (a) {
124
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125
+ +a[5], +a[6]));
126
+ }
127
+ }
128
+ return value;
129
+ });
130
+
131
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132
+ var d;
133
+ if (typeof value === 'string' &&
134
+ value.slice(0, 5) === 'Date(' &&
135
+ value.slice(-1) === ')') {
136
+ d = new Date(value.slice(5, -1));
137
+ if (d) {
138
+ return d;
139
+ }
140
+ }
141
+ return value;
142
+ });
143
+
144
+
145
+ This is a reference implementation. You are free to copy, modify, or
146
+ redistribute.
147
+ */
148
+
149
+ /*jslint evil: true, strict: false, regexp: false */
150
+
151
+ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
155
+ test, toJSON, toString, valueOf
156
+ */
157
+
158
+
159
+ // Create a JSON object only if one does not already exist. We create the
160
+ // methods in a closure to avoid creating global variables.
161
+
162
+ var JSON;
163
+ if (!JSON) {
164
+ JSON = {};
165
+ }
166
+
167
+ (function () {
168
+ "use strict";
169
+
170
+ function f(n) {
171
+ // Format integers to have at least two digits.
172
+ return n < 10 ? '0' + n : n;
173
+ }
174
+
175
+ if (typeof Date.prototype.toJSON !== 'function') {
176
+
177
+ Date.prototype.toJSON = function (key) {
178
+
179
+ return isFinite(this.valueOf()) ?
180
+ this.getUTCFullYear() + '-' +
181
+ f(this.getUTCMonth() + 1) + '-' +
182
+ f(this.getUTCDate()) + 'T' +
183
+ f(this.getUTCHours()) + ':' +
184
+ f(this.getUTCMinutes()) + ':' +
185
+ f(this.getUTCSeconds()) + 'Z' : null;
186
+ };
187
+
188
+ String.prototype.toJSON =
189
+ Number.prototype.toJSON =
190
+ Boolean.prototype.toJSON = function (key) {
191
+ return this.valueOf();
192
+ };
193
+ }
194
+
195
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
196
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
197
+ gap,
198
+ indent,
199
+ meta = { // table of character substitutions
200
+ '\b': '\\b',
201
+ '\t': '\\t',
202
+ '\n': '\\n',
203
+ '\f': '\\f',
204
+ '\r': '\\r',
205
+ '"' : '\\"',
206
+ '\\': '\\\\'
207
+ },
208
+ rep;
209
+
210
+
211
+ function quote(string) {
212
+
213
+ // If the string contains no control characters, no quote characters, and no
214
+ // backslash characters, then we can safely slap some quotes around it.
215
+ // Otherwise we must also replace the offending characters with safe escape
216
+ // sequences.
217
+
218
+ escapable.lastIndex = 0;
219
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220
+ var c = meta[a];
221
+ return typeof c === 'string' ? c :
222
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
223
+ }) + '"' : '"' + string + '"';
224
+ }
225
+
226
+
227
+ function str(key, holder) {
228
+
229
+ // Produce a string from holder[key].
230
+
231
+ var i, // The loop counter.
232
+ k, // The member key.
233
+ v, // The member value.
234
+ length,
235
+ mind = gap,
236
+ partial,
237
+ value = holder[key];
238
+
239
+ // If the value has a toJSON method, call it to obtain a replacement value.
240
+
241
+ if (value && typeof value === 'object' &&
242
+ typeof value.toJSON === 'function') {
243
+ value = value.toJSON(key);
244
+ }
245
+
246
+ // If we were called with a replacer function, then call the replacer to
247
+ // obtain a replacement value.
248
+
249
+ if (typeof rep === 'function') {
250
+ value = rep.call(holder, key, value);
251
+ }
252
+
253
+ // What happens next depends on the value's type.
254
+
255
+ switch (typeof value) {
256
+ case 'string':
257
+ return quote(value);
258
+
259
+ case 'number':
260
+
261
+ // JSON numbers must be finite. Encode non-finite numbers as null.
262
+
263
+ return isFinite(value) ? String(value) : 'null';
264
+
265
+ case 'boolean':
266
+ case 'null':
267
+
268
+ // If the value is a boolean or null, convert it to a string. Note:
269
+ // typeof null does not produce 'null'. The case is included here in
270
+ // the remote chance that this gets fixed someday.
271
+
272
+ return String(value);
273
+
274
+ // If the type is 'object', we might be dealing with an object or an array or
275
+ // null.
276
+
277
+ case 'object':
278
+
279
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
280
+ // so watch out for that case.
281
+
282
+ if (!value) {
283
+ return 'null';
284
+ }
285
+
286
+ // Make an array to hold the partial results of stringifying this object value.
287
+
288
+ gap += indent;
289
+ partial = [];
290
+
291
+ // Is the value an array?
292
+
293
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
294
+
295
+ // The value is an array. Stringify every element. Use null as a placeholder
296
+ // for non-JSON values.
297
+
298
+ length = value.length;
299
+ for (i = 0; i < length; i += 1) {
300
+ partial[i] = str(i, value) || 'null';
301
+ }
302
+
303
+ // Join all of the elements together, separated with commas, and wrap them in
304
+ // brackets.
305
+
306
+ v = partial.length === 0 ? '[]' : gap ?
307
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
308
+ '[' + partial.join(',') + ']';
309
+ gap = mind;
310
+ return v;
311
+ }
312
+
313
+ // If the replacer is an array, use it to select the members to be stringified.
314
+
315
+ if (rep && typeof rep === 'object') {
316
+ length = rep.length;
317
+ for (i = 0; i < length; i += 1) {
318
+ if (typeof rep[i] === 'string') {
319
+ k = rep[i];
320
+ v = str(k, value);
321
+ if (v) {
322
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
323
+ }
324
+ }
325
+ }
326
+ } else {
327
+
328
+ // Otherwise, iterate through all of the keys in the object.
329
+
330
+ for (k in value) {
331
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
332
+ v = str(k, value);
333
+ if (v) {
334
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ // Join all of the member texts together, separated with commas,
341
+ // and wrap them in braces.
342
+
343
+ v = partial.length === 0 ? '{}' : gap ?
344
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
345
+ '{' + partial.join(',') + '}';
346
+ gap = mind;
347
+ return v;
348
+ }
349
+ }
350
+
351
+ // If the JSON object does not yet have a stringify method, give it one.
352
+
353
+ if (typeof JSON.stringify !== 'function') {
354
+ JSON.stringify = function (value, replacer, space) {
355
+
356
+ // The stringify method takes a value and an optional replacer, and an optional
357
+ // space parameter, and returns a JSON text. The replacer can be a function
358
+ // that can replace values, or an array of strings that will select the keys.
359
+ // A default replacer method can be provided. Use of the space parameter can
360
+ // produce text that is more easily readable.
361
+
362
+ var i;
363
+ gap = '';
364
+ indent = '';
365
+
366
+ // If the space parameter is a number, make an indent string containing that
367
+ // many spaces.
368
+
369
+ if (typeof space === 'number') {
370
+ for (i = 0; i < space; i += 1) {
371
+ indent += ' ';
372
+ }
373
+
374
+ // If the space parameter is a string, it will be used as the indent string.
375
+
376
+ } else if (typeof space === 'string') {
377
+ indent = space;
378
+ }
379
+
380
+ // If there is a replacer, it must be a function or an array.
381
+ // Otherwise, throw an error.
382
+
383
+ rep = replacer;
384
+ if (replacer && typeof replacer !== 'function' &&
385
+ (typeof replacer !== 'object' ||
386
+ typeof replacer.length !== 'number')) {
387
+ throw new Error('JSON.stringify');
388
+ }
389
+
390
+ // Make a fake root object containing our value under the key of ''.
391
+ // Return the result of stringifying the value.
392
+
393
+ return str('', {'': value});
394
+ };
395
+ }
396
+
397
+
398
+ // If the JSON object does not yet have a parse method, give it one.
399
+
400
+ if (typeof JSON.parse !== 'function') {
401
+ JSON.parse = function (text, reviver) {
402
+
403
+ // The parse method takes a text and an optional reviver function, and returns
404
+ // a JavaScript value if the text is a valid JSON text.
405
+
406
+ var j;
407
+
408
+ function walk(holder, key) {
409
+
410
+ // The walk method is used to recursively walk the resulting structure so
411
+ // that modifications can be made.
412
+
413
+ var k, v, value = holder[key];
414
+ if (value && typeof value === 'object') {
415
+ for (k in value) {
416
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
417
+ v = walk(value, k);
418
+ if (v !== undefined) {
419
+ value[k] = v;
420
+ } else {
421
+ delete value[k];
422
+ }
423
+ }
424
+ }
425
+ }
426
+ return reviver.call(holder, key, value);
427
+ }
428
+
429
+
430
+ // Parsing happens in four stages. In the first stage, we replace certain
431
+ // Unicode characters with escape sequences. JavaScript handles many characters
432
+ // incorrectly, either silently deleting them, or treating them as line endings.
433
+
434
+ text = String(text);
435
+ cx.lastIndex = 0;
436
+ if (cx.test(text)) {
437
+ text = text.replace(cx, function (a) {
438
+ return '\\u' +
439
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
440
+ });
441
+ }
442
+
443
+ // In the second stage, we run the text against regular expressions that look
444
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
445
+ // because they can cause invocation, and '=' because it can cause mutation.
446
+ // But just to be safe, we want to reject all unexpected forms.
447
+
448
+ // We split the second stage into 4 regexp operations in order to work around
449
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
450
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
451
+ // replace all simple value tokens with ']' characters. Third, we delete all
452
+ // open brackets that follow a colon or comma or that begin the text. Finally,
453
+ // we look to see that the remaining characters are only whitespace or ']' or
454
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
455
+
456
+ if (/^[\],:{}\s]*$/
457
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
458
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
459
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
460
+
461
+ // In the third stage we use the eval function to compile the text into a
462
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
463
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
464
+ // in parens to eliminate the ambiguity.
465
+
466
+ j = eval('(' + text + ')');
467
+
468
+ // In the optional fourth stage, we recursively walk the new structure, passing
469
+ // each name/value pair to a reviver function for possible transformation.
470
+
471
+ return typeof reviver === 'function' ?
472
+ walk({'': j}, '') : j;
473
+ }
474
+
475
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
476
+
477
+ throw new SyntaxError('JSON.parse');
478
+ };
479
+ }
480
+ }());
skin/adminhtml/default/default/edq/js/system.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var EDQ = EDQ || {};
2
+ EDQ.system = EDQ.system || {};
3
+
4
+ EDQ.system.isUndefined = function isUndefined(value) { return typeof(value) == "undefined"; };
5
+ EDQ.system.isNull = function isNull(value) { return EDQ.system.isUndefined(value) || value == null; };
6
+ EDQ.system.isNullOrEmpty = function isNullOrEmpty(str) { return EDQ.system.isNull(str) || str == ""; };
7
+ EDQ.system.isFunction = function isFunction(obj) { return !EDQ.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Function]'; };
8
+ EDQ.system.logError = function logError(obj) {
9
+ if (window.console) {
10
+ window.console.log(obj);
11
+ } else { //IE does not have a logger.
12
+ //alert(obj);
13
+ };
14
+ };
15
+
16
+ EDQ.system.inherit = (function () {
17
+ var F = function (){};
18
+ return function (C, P) {
19
+ F.prototype = P.prototype;
20
+ C.prototype = new F();
21
+ C.uber = P.prototype;
22
+ C.prototype.constructor = C;
23
+ }
24
+ }());
25
+
26
+ if (Array && !Array.indexOf){
27
+ Array.prototype.indexOf = function (elt /*, from*/) {
28
+ var len = this.length;
29
+
30
+ var from = Number(arguments[1]) || 0;
31
+ from = (from < 0)? Math.ceil(from) : Math.floor(from);
32
+ if (from < 0) { from += len; }
33
+ for (; from < len; from++) {
34
+ if (from in this && this[from] === elt) { return from;}
35
+ }
36
+ return -1;
37
+ };
38
+ };
39
+
40
+ EDQ.system.getById = function getById(selector) {
41
+ return document.getElementById(selector);
42
+ };
43
+
44
+ EDQ.system.beginsWith = function beginsWith(needle, haystack) {
45
+ return (haystack.substr(0, needle.length) == needle);
46
+ };
skin/frontend/base/default/ExperianDataQuality/images/opc-ajax-loader.gif ADDED
Binary file
skin/frontend/base/default/ExperianDataQuality/js/edqAddressClient.js ADDED
@@ -0,0 +1,611 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ExperianDataQuality.DataQuality.Address = ExperianDataQuality.DataQuality.Address || {};
2
+
3
+ ExperianDataQuality.DataQuality.Address.Configuration = function Configuration(inputMappings, outputMappings) {
4
+ var dq = ExperianDataQuality.DataQuality;
5
+
6
+ this._stage = dq.WorkFlowStages.Input;
7
+
8
+ dq.Configuration.apply(this, [inputMappings, outputMappings, dq.ConfigurationType.Address]);
9
+ };
10
+ ExperianDataQuality.system.inherit(ExperianDataQuality.DataQuality.Address.Configuration, ExperianDataQuality.DataQuality.Configuration);
11
+ ExperianDataQuality.DataQuality.Address.Configuration.SearchServiceUrl = '';
12
+ ExperianDataQuality.DataQuality.Address.Configuration.RefineServiceUrl = '';
13
+ ExperianDataQuality.DataQuality.Address.Configuration.GetAddressServiceUrl = '';
14
+ ExperianDataQuality.DataQuality.Address.Configuration.IsManualEntryAllowed = true;
15
+
16
+ ExperianDataQuality.DataQuality.Address.Client = function Client(configurations) {
17
+ var dq = ExperianDataQuality.DataQuality;
18
+
19
+ dq.Client.apply(this, [configurations]);
20
+ };
21
+ ExperianDataQuality.system.inherit(ExperianDataQuality.DataQuality.Address.Client, ExperianDataQuality.DataQuality.Client);
22
+
23
+ ExperianDataQuality.DataQuality.Address.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) {
24
+ var sys = ExperianDataQuality.system;
25
+ var dq = ExperianDataQuality.DataQuality;
26
+
27
+ var client = this;
28
+
29
+ var dataSetElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.DataSet);
30
+ if (sys.isNull(dataSetElement)) {
31
+ return;
32
+ }
33
+
34
+ var previousOnChange = dataSetElement.onchange;
35
+ dataSetElement.onchange = function (event, value) {
36
+ dq.ManualEntryState = dq.Deactive;
37
+ if (sys.isFunction(previousOnChange)) {
38
+ previousOnChange.apply(this, [event]);
39
+ };
40
+ if(sys.containsInArray(dataSetElement.value, dq.Address.LicensedDataSets) && client._isExistingAddressEdited(configuration) === false) {
41
+ client._showVerifiedAddressPromptSet(configuration, false, dataSetElement.value);
42
+ }
43
+ else {
44
+ client._showPromptSetFor(configuration, this.value);
45
+ }
46
+ };
47
+ dataSetElement.onchange();
48
+
49
+ var chagenAddressElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.ChangeAddressButton);
50
+ chagenAddressElement.onclick = function () { dq.ManualEntryState = dq.Deactive; client._showPromptSetFor(configuration, dataSetElement.value); };
51
+
52
+ var findAddressElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.FindAddressButton);
53
+ findAddressElement.onclick = function () { client._findAddress(configuration); };
54
+
55
+ var manualEntryElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.ManualEntry);
56
+ if(!sys.isNull(manualEntryElement)) {
57
+ manualEntryElement.onclick = function () { client._showPromptSetFor(configuration); dq.ManualEntryState = dq.Active; };
58
+ }
59
+
60
+ var knownPostCodeElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.KnownPostCode);
61
+ knownPostCodeElement.onclick = function () { client._showPromptSetFor(configuration, dataSetElement.value); };
62
+
63
+ var unknownPostCodeElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.UnknownPostCode);
64
+ unknownPostCodeElement.onclick = function () { client._showUnknownPostcodePromptSet(configuration, dataSetElement.value); };
65
+
66
+ var selectSuggestionButtonElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.SelectButton);
67
+ selectSuggestionButtonElement.onclick = function () { client._selectAddress(dataSetElement.value, configuration); };
68
+
69
+ var suggestionsElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
70
+ suggestionsElement.ondblclick = function (event) { client._selectAddress(dataSetElement.value, configuration); };
71
+
72
+ var refineElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.RefineInput);
73
+
74
+ var tryAgainElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.TryAgain);
75
+ tryAgainElement.onclick = function () {
76
+ switch (configuration.stage) {
77
+ case dq.WorkFlowStages.Suggestions:
78
+ client._restoreInputValues(configuration._inputMappings);
79
+ client._selectAddress(dataSetElement.value, configuration);
80
+ break;
81
+ case dq.WorkFlowStages.Refining:
82
+ client._restoreInputValues(configuration._inputMappings);
83
+ client._refineAddress(dataSetElement.value, refineElement.value, configuration);
84
+ break;
85
+ default:
86
+ client._restoreInputValues(configuration._inputMappings);
87
+ client._findAddress(configuration);
88
+ break;
89
+ }
90
+ };
91
+
92
+ var backButtonElements = configuration._getHtmlElementsFromInputMappingByEdqFieldName(dq.BackButton);
93
+
94
+ var backButtonElementOnClick = function () {
95
+ switch (configuration.stage) {
96
+ case dq.WorkFlowStages.Verified:
97
+ if (suggestionsElement.options.length <= 1) {
98
+ client._showPromptSetFor(configuration, dataSetElement.value);
99
+ client._restoreInputValues(configuration._inputMappings);
100
+ break;
101
+ }
102
+ client._showSuggestionsProptset(configuration);
103
+ break;
104
+ case dq.WorkFlowStages.Refining:
105
+ if (suggestionsElement.options.length <= 1) {
106
+ client._showPromptSetFor(configuration, dataSetElement.value);
107
+ client._restoreInputValues(configuration._inputMappings);
108
+ } else {
109
+ client._showSuggestionsProptset(configuration);
110
+ }
111
+ break;
112
+ case dq.WorkFlowStages.Suggestions:
113
+ dq.Address.Client.clearSuggestionList(suggestionsElement);
114
+ client._showPromptSetFor(configuration, dataSetElement.value);
115
+ client._restoreInputValues(configuration._inputMappings);
116
+ break;
117
+ default:
118
+ client._showPromptSetFor(configuration, dataSetElement.value);
119
+ client._restoreInputValues(configuration._inputMappings);
120
+ break;
121
+ }
122
+ client._handleErrorMessage(configuration, dq.ErrorMessage);
123
+ };
124
+
125
+ for(var i = 0, max = backButtonElements.length; i < max; i++) {
126
+ var backButtonHtmlElement = sys.getElementById(backButtonElements[i]);
127
+
128
+ backButtonHtmlElement.onclick = backButtonElementOnClick;
129
+ }
130
+
131
+ var nextButtonElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.NextButton);
132
+ nextButtonElement.onclick = function () { client._refineAddress(dataSetElement.value, refineElement.value, configuration); };
133
+ };
134
+
135
+ ExperianDataQuality.DataQuality.Address.Client.prototype._isExistingAddressEdited = function _isExistingAddressEdited(configuration) {
136
+ var sys = ExperianDataQuality.system;
137
+ var dq = ExperianDataQuality.DataQuality;
138
+
139
+ var areAllFieldsEmpty = true;
140
+
141
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
142
+ var inputMapping = configuration._inputMappings[i];
143
+
144
+ var value = dq.Client.collectValuesFromInputMapping(inputMapping);
145
+
146
+ switch (inputMapping.edqFieldName) {
147
+ case dq.Line1:
148
+ case dq.Line2:
149
+ case dq.Line3:
150
+ case dq.Line4:
151
+ case dq.Line5:
152
+ if (!sys.isNullOrEmpty(value)) {
153
+ areAllFieldsEmpty = false;
154
+ }
155
+ dq.Snapshot[inputMapping.edqFieldName] = value;
156
+ break;
157
+ default:
158
+ break;
159
+ }
160
+ }
161
+
162
+ return areAllFieldsEmpty;
163
+ };
164
+
165
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showPromptSetFor = function _showPromptSetFor(configuration, dataSet) {
166
+ var sys = ExperianDataQuality.system;
167
+ var dq = ExperianDataQuality.DataQuality;
168
+
169
+ if(dq.ManualEntryState === dq.Active) {
170
+ return;
171
+ }
172
+
173
+ var visibleElements = [];
174
+ if (sys.containsInArray(dataSet, dq.Address.LicensedDataSets)) {
175
+ switch(dataSet) {
176
+ case 'GB':
177
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Postcode, dq.UnknownPostCode];
178
+ break;
179
+ case 'DE':
180
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Postcode, dq.UnknownPostCode, dq.Street];
181
+ break;
182
+ case 'IE':
183
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.Town, dq.Street];
184
+ break;
185
+ }
186
+ if( dq.Address.Configuration.IsManualEntryAllowed) { visibleElements.push(dq.ManualEntry); }
187
+ }
188
+ else {
189
+ visibleElements = [dq.Line1, dq.Line2, dq.Line3, dq.Line4, dq.Line5, dq.DataSet];
190
+ }
191
+
192
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, visibleElements);
193
+ this._handleErrorMessage(configuration, dq.ErrorMessage);
194
+ configuration.stage = dq.WorkFlowStages.Input;
195
+ };
196
+
197
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showUnknownPostcodePromptSet = function _showUnknownPostcodePromptSet(configuration, dataSet) {
198
+ var dq = ExperianDataQuality.DataQuality;
199
+
200
+ if(dq.ManualEntryState === dq.Active) {
201
+ return;
202
+ }
203
+
204
+ var visibleElements;
205
+ if(dataSet === 'GB' || dataSet === 'DE') {
206
+ visibleElements = [dq.DataSet, dq.FindAddressButton, dq.BuildingNumber, dq.ManualEntry, dq.Town, dq.Street, dq.KnownPostCode];
207
+ }
208
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, visibleElements);
209
+ configuration.stage = dq.WorkFlowStages.Input;
210
+ };
211
+
212
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showSuggestionsProptset = function _showSuggestionsProptset(configuration) {
213
+ var dq = ExperianDataQuality.DataQuality;
214
+
215
+ if(dq.ManualEntryState === dq.Active) {
216
+ return;
217
+ }
218
+
219
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.BackButton, dq.SelectButton, dq.Suggestions, dq.ManualEntry]);
220
+ configuration.stage = dq.WorkFlowStages.Suggestions;
221
+ };
222
+
223
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showRefineInputPromptSet = function _showRefineInputPromptSet(configuration) {
224
+ var dq = ExperianDataQuality.DataQuality;
225
+
226
+ if(dq.ManualEntryState === dq.Active) {
227
+ return;
228
+ }
229
+
230
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.RefineInput, dq.BackButton, dq.NextButton, dq.ManualEntry]);
231
+ configuration.stage = dq.WorkFlowStages.Refining;
232
+ };
233
+
234
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showVerifiedAddressPromptSet = function _showVerifiedAddressPromptSet(configuration, isVerified, dataSet) {
235
+ var dq = ExperianDataQuality.DataQuality;
236
+
237
+ if(dq.ManualEntryState === dq.Active) {
238
+ return;
239
+ }
240
+
241
+ var vasableElements = [dq.Line1, dq.Line2, dq.Line3, dq.Line4, dq.Line5, dq.DataSet];
242
+
243
+ if(isVerified) {
244
+ configuration.stage = dq.WorkFlowStages.Verified;
245
+ vasableElements.push(dq.BackButton);
246
+ } else {
247
+ vasableElements.push(dq.ChangeAddressButton);
248
+ }
249
+
250
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, vasableElements);
251
+ };
252
+
253
+ ExperianDataQuality.DataQuality.Address.Client.prototype._findAddress = function _findAddress(configuration) {
254
+ var sys = ExperianDataQuality.system;
255
+ var dq = ExperianDataQuality.DataQuality;
256
+
257
+ var parameters = {};
258
+ var areAllFieldsEmpty = true;
259
+
260
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
261
+ var inputMapping = configuration._inputMappings[i];
262
+
263
+ var value = dq.Client.collectValuesFromInputMapping(inputMapping);
264
+ //TBD
265
+ switch (inputMapping.edqFieldName) {
266
+ case dq.DataSet:
267
+ case dq.Street:
268
+ case dq.BuildingNumber:
269
+ case dq.Town:
270
+ case dq.Postcode:
271
+ if (inputMapping.edqFieldName !== dq.DataSet && !sys.isNullOrEmpty(value)) {
272
+ areAllFieldsEmpty = false;
273
+ }
274
+ parameters[inputMapping.edqFieldName] = value;
275
+ dq.Snapshot[inputMapping.edqFieldName] = value;
276
+ break;
277
+ default:
278
+ break;
279
+ }
280
+ }
281
+
282
+ if (areAllFieldsEmpty) {
283
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
284
+ return;
285
+ }
286
+
287
+ this._executeFindAddressRequest(configuration, parameters, dq.Address.Configuration.SearchServiceUrl);
288
+ };
289
+
290
+ ExperianDataQuality.DataQuality.Address.Client.prototype._refineAddress = function _refineAddress(dataSet, refineInput, configuration) {
291
+ var sys = ExperianDataQuality.system;
292
+ var dq = ExperianDataQuality.DataQuality;
293
+
294
+ if (sys.isNullOrEmpty(refineInput)) {
295
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
296
+ return;
297
+ }
298
+
299
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
300
+ if (sys.isNull(suggestionsHtmlElement) || sys.isNull(suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex])) {
301
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage, configuration);
302
+ return;
303
+ }
304
+
305
+ var partialText = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].innerHTML;
306
+ var unresolvableRange = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['range'].value;
307
+
308
+ if (!this._validateRefinementInput(refineInput, partialText, unresolvableRange)) {
309
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage, configuration);
310
+ return;
311
+ }
312
+
313
+ var parameters = {};
314
+ parameters[dq.Moniker] = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].value;
315
+ parameters[dq.RefineInput] = refineInput;
316
+ parameters[dq.DataSet] = dataSet;
317
+
318
+ dq.Snapshot[dq.RefineInput] = refineInput;
319
+
320
+ this._executeFindAddressRequest(configuration, parameters, dq.Address.Configuration.RefineServiceUrl);
321
+ };
322
+
323
+ ExperianDataQuality.DataQuality.Address.Client.prototype._validateRefinementInput = function _validateRefinementInput(refineInput, partialAddress, unresolvableRange) {
324
+ var dq = ExperianDataQuality.DataQuality;
325
+ var sys = ExperianDataQuality.system;
326
+
327
+ if (refineInput.length > 40) { return false; }
328
+
329
+ if (!sys.toBoolean(unresolvableRange)) { return true; }
330
+
331
+ var range = partialAddress.match(/[0-9a-zA-Z]+\s[...]+\s[0-9a-zA-Z]+/gim)[0].split('...');
332
+ if (range.length > 2) {
333
+ return true;
334
+ }
335
+
336
+ var startRange = isNaN(parseInt(range[0].trim())) ? range[0].trim() : parseInt(range[0].trim());
337
+ var endRange = isNaN(parseInt(range[1].trim())) ? range[1].trim() : parseInt(range[1].trim());
338
+ var castedInput = isNaN(parseInt(refineInput.trim())) ? refineInput.trim() : parseInt(refineInput.trim());
339
+
340
+ var isValid = true;
341
+ if (castedInput < startRange || castedInput > endRange) {
342
+ isValid = false;
343
+ } else {
344
+ var criteria = partialAddress.substr(partialAddress.indexOf('['), partialAddress.indexOf(']'));
345
+
346
+ if (sys.isNullOrEmpty(criteria) && isNaN(castedInput)) {
347
+ isValid = false;
348
+ } else {
349
+ if (sys.beginsWith('[even]', criteria) || sys.endsWith('[even]', criteria)) {
350
+ isValid = (!isNaN(castedInput % 2) && castedInput % 2 === 0);
351
+ }
352
+ if (sys.beginsWith('[odd]', criteria) || sys.endsWith('[odd]', criteria)) {
353
+ isValid = (!isNaN(castedInput % 2) && castedInput % 2 !== 0);
354
+ }
355
+ }
356
+ }
357
+
358
+ return isValid;
359
+ };
360
+
361
+ ExperianDataQuality.DataQuality.Address.Client.prototype._executeFindAddressRequest = function _executeFindAddressRequest(configuration, parameters, url) {
362
+ var sys = ExperianDataQuality.system;
363
+ var dq = ExperianDataQuality.DataQuality;
364
+ var addressClient = dq.Address.Client;
365
+
366
+ var client = this;
367
+
368
+ client._handleLoader(configuration, true);
369
+ this._executeXMLHttpRequest(url, parameters, function (response, errorMessage, xhr) {
370
+ client._handleLoader(configuration, false);
371
+
372
+ if (!sys.isNullOrEmpty(errorMessage)) {
373
+ client._promptSetForErrorMessage(errorMessage, configuration);
374
+ return;
375
+ }
376
+
377
+ if(!sys.isNull(response.AddressLineDictionary)) {
378
+ client.setValues(response.AddressLineDictionary, configuration);
379
+ client._showVerifiedAddressPromptSet(configuration, true, parameters[dq.DataSet]);
380
+ return;
381
+ }
382
+
383
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
384
+ if (response.Total < 2) {
385
+ var details = response.PickListEntries[0];
386
+
387
+ if (details && details.PickList === 'No matches' || details.PickList === 'Search cancelled (too many matches)') {
388
+ details.PickList = details.PickList === 'No matches' ? ExperianDataQuality.DataQuality.Address.NoMatchesMessage : ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage;
389
+ client._showErrorMessage(details.PickList, configuration);
390
+ return;
391
+ }
392
+
393
+ if(details.FullAddress) {
394
+ client._getAddress(parameters[dq.DataSet], details.Moniker, configuration);
395
+ return;
396
+ }
397
+
398
+ addressClient.populateSuggestionList(suggestionsHtmlElement, response.PickListEntries, response.Prompt);
399
+ suggestionsHtmlElement.options[0].selected = true;
400
+ client._selectAddress(parameters[dq.DataSet], configuration);
401
+ } else {
402
+ var suggestionsHtmlElementLabel = configuration._getHtmlElementLabelFromInputMappingByEdqFieldName(dq.Suggestions);
403
+ suggestionsHtmlElementLabel.innerHTML = response.Prompt === 'Enter selection' ? ExperianDataQuality.DataQuality.Address.EnterSelection : 'Enter selection';
404
+
405
+ addressClient.populateSuggestionList(suggestionsHtmlElement, response.PickListEntries, response.Prompt);
406
+ client._showSuggestionsProptset(configuration);
407
+ }
408
+ });
409
+ };
410
+
411
+ ExperianDataQuality.DataQuality.Address.Client.populateSuggestionList = function populateSuggestionList(suggestionsHtmlElement, options, prompt) {
412
+ var dq = ExperianDataQuality.DataQuality;
413
+
414
+ suggestionsHtmlElement.innerHTML = '';
415
+ for (var i = 0; i < options.length; i++) {
416
+ var element = document.createElement(dq.HtmlTags.Option);
417
+ element.innerHTML = options[i].PickList + ' ' + options[i].Postcode;
418
+ element.textContent = options[i].PickList + ' ' + options[i].Postcode;
419
+ element.value = options[i].Moniker;
420
+ element.setAttribute('range', options[i].UnresolvableRange);
421
+ element.setAttribute('full', options[i].FullAddress);
422
+ element.setAttribute('prompt', prompt);
423
+ suggestionsHtmlElement.appendChild(element);
424
+ }
425
+ };
426
+
427
+ ExperianDataQuality.DataQuality.Address.Client.clearSuggestionList = function clearSuggestionList(suggestionsHtmlElement) {
428
+ if (suggestionsHtmlElement === null) { return; }
429
+ if (suggestionsHtmlElement.options === null) { return; }
430
+ while (suggestionsHtmlElement.options.length > 0) {
431
+ suggestionsHtmlElement.remove(0);
432
+ }
433
+ suggestionsHtmlElement.multiple = true;
434
+ };
435
+
436
+ ExperianDataQuality.DataQuality.Address.Client.prototype._selectAddress = function _selectAddress(dataSet, configuration) {
437
+ var sys = ExperianDataQuality.system;
438
+ var dq = ExperianDataQuality.DataQuality;
439
+
440
+ var suggestionsHtmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(dq.Suggestions);
441
+
442
+ if (sys.isNull(suggestionsHtmlElement) || suggestionsHtmlElement.selectedIndex === -1) {
443
+ this._showErrorMessage(ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions, configuration);
444
+ return;
445
+ }
446
+
447
+ var isFullAddress = sys.toBoolean(suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['full'].value);
448
+ if (isFullAddress) {
449
+ var moniker = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].value;
450
+ this._getAddress(dataSet, moniker, configuration);
451
+ } else {
452
+ var refineInputHtmlElementLabel = configuration._getHtmlElementLabelFromInputMappingByEdqFieldName(dq.RefineInput);
453
+ var prompt = suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].attributes['prompt'].value;
454
+ refineInputHtmlElementLabel.innerHTML = ExperianDataQuality.DataQuality.Address.RefinementText + ' ' + suggestionsHtmlElement.options[suggestionsHtmlElement.selectedIndex].innerHTML;
455
+
456
+ this._showRefineInputPromptSet(configuration);
457
+ }
458
+ };
459
+
460
+ ExperianDataQuality.DataQuality.Address.Client.prototype._getAddress = function _getAddress(dataSet, moniker, configuration) {
461
+ var sys = ExperianDataQuality.system;
462
+ var dq = ExperianDataQuality.DataQuality;
463
+
464
+ var parameters = {};
465
+ parameters[dq.Moniker] = moniker;
466
+ parameters[dq.DataSet] = dataSet;
467
+
468
+ var client = this;
469
+ client._handleLoader(configuration, true);
470
+ this._executeXMLHttpRequest(dq.Address.Configuration.GetAddressServiceUrl, parameters, function (response, errorMessage, xhr) {
471
+ client._handleLoader(configuration, false);
472
+
473
+ if (!sys.isNullOrEmpty(errorMessage)) {
474
+ client._promptSetForErrorMessage(errorMessage, configuration);
475
+ return;
476
+ }
477
+
478
+ client.setValues(response.AddressLineDictionary, configuration);
479
+ client._showVerifiedAddressPromptSet(configuration, true, dataSet);
480
+ });
481
+ };
482
+
483
+ ExperianDataQuality.DataQuality.Address.Client.prototype._promptSetForErrorMessage = function _promptSetForErrorMessage(errorMessage, configuration) {
484
+ var dq = ExperianDataQuality.DataQuality;
485
+
486
+ this._showErrorMessage(errorMessage, configuration);
487
+ this._hideAllInputMappingElementsExcept(configuration._inputMappings, [dq.ManualEntry, dq.BackButton, dq.TryAgain, dq.ErrorMessage]);
488
+ };
489
+
490
+ ExperianDataQuality.DataQuality.Address.Client.prototype._showErrorMessage = function _showErrorMessage(message, configuration) {
491
+ var dq = ExperianDataQuality.DataQuality;
492
+ var sys = ExperianDataQuality.system;
493
+
494
+ var errorMessageOutputMapping = configuration._getOutputMappingByEdqFieldName(dq.ErrorMessage);
495
+ var errorMessageHtmlElement = sys.getElementById(errorMessageOutputMapping.htmlElementId);
496
+ if (sys.isNull(errorMessageHtmlElement)) {
497
+ return;
498
+ }
499
+
500
+ if (errorMessageHtmlElement.tagName === dq.HtmlTags.Label || errorMessageHtmlElement.tagName === dq.HtmlTags.Div) {
501
+ errorMessageHtmlElement.innerHTML = message;
502
+ } else {
503
+ errorMessageHtmlElement.value = message;
504
+ }
505
+ dq.Client.showElement(errorMessageHtmlElement);
506
+ };
507
+
508
+ ExperianDataQuality.DataQuality.Address.Client.prototype._restoreInputValues = function _restoreInputValues(mapping) {
509
+ var dq = ExperianDataQuality.DataQuality;
510
+ var sys = ExperianDataQuality.system;
511
+
512
+ for (var i = 0, max = mapping.length; i < max; i++) {
513
+ var field = sys.getElementById(mapping[i].htmlElementIds[0]);
514
+ if (sys.isNull(field)) {
515
+ continue;
516
+ }
517
+
518
+ switch (mapping[i].edqFieldName) {
519
+ case dq.DataSet:
520
+ case dq.Street:
521
+ case dq.City:
522
+ case dq.State:
523
+ case dq.Postcode:
524
+ case dq.BuildingNumber:
525
+ case dq.Postcode:
526
+ case dq.Town:
527
+ case dq.RefineInput:
528
+ case dq.Line1:
529
+ case dq.Line2:
530
+ case dq.Line3:
531
+ case dq.Line4:
532
+ case dq.Line5:
533
+ if (dq.Snapshot[mapping[i].edqFieldName] !== undefined) {
534
+ field.value = dq.Snapshot[mapping[i].edqFieldName];
535
+ }
536
+ break;
537
+ default:
538
+ continue;
539
+ }
540
+ }
541
+ };
542
+
543
+ ExperianDataQuality.DataQuality.Address.Client.prototype._handleLoader = function _handleLoader(configuration, showLoader) {
544
+ var dq = ExperianDataQuality.DataQuality;
545
+ var sys = ExperianDataQuality.system;
546
+
547
+ var loader = null;
548
+ this._handleErrorMessage(configuration, dq.ErrorMessage);
549
+ for (var i = 0, max = configuration._inputMappings.length; i < max; i++) {
550
+ var fieldName = configuration._inputMappings[i].edqFieldName;
551
+ var htmlElement = null;
552
+
553
+ if(fieldName === dq.BackButton) {
554
+ htmlElement = configuration._getHtmlElementsFromInputMappingByEdqFieldName(fieldName);
555
+ } else {
556
+ htmlElement = configuration._getHtmlElementFromInputMappingByEdqFieldName(fieldName);
557
+ }
558
+
559
+ if(sys.isArray(htmlElement)) {
560
+ for(var j = 0, max2 = htmlElement.length; j < max2; j++) {
561
+ var element = sys.getElementById(htmlElement[j]);
562
+
563
+ if (sys.isNull(element)) {
564
+ continue;
565
+ }
566
+
567
+ if(element.tagName === dq.HtmlTags.Button || element.tagName === dq.HtmlTags.Select) {
568
+ element.disabled = showLoader ? true : false;
569
+ }
570
+ }
571
+ } else {
572
+ if (sys.isNull(htmlElement)) {
573
+ continue;
574
+ }
575
+
576
+ if(htmlElement.tagName === dq.HtmlTags.Button || htmlElement.tagName === dq.HtmlTags.Select) {
577
+ htmlElement.disabled = showLoader ? true : false;
578
+ }
579
+ }
580
+
581
+ if(fieldName === dq.Loader) {
582
+ loader = htmlElement;
583
+ }
584
+
585
+ if(fieldName === dq.UnknownPostCode || fieldName === dq.KnownPostCode) {
586
+ if(showLoader) {
587
+ htmlElement.oldEvent = htmlElement.onclick;
588
+ htmlElement.onclick = null;
589
+ } else {
590
+ if(htmlElement.onclick === null) {
591
+ htmlElement.onclick = htmlElement.oldEvent;
592
+ }
593
+ }
594
+ }
595
+ }
596
+
597
+ if(showLoader) {
598
+ dq.Client.showElement(loader);
599
+ } else {
600
+ dq.Client.hideElement(loader);
601
+ }
602
+ };
603
+
604
+ ExperianDataQuality.DataQuality.Address.LicensedDataSets = ExperianDataQuality.DataQuality.Address.LicensedDataSets || [];
605
+ ExperianDataQuality.DataQuality.Address.EnterSelection = ExperianDataQuality.DataQuality.Address.EnterSelection || 'Enter selection';
606
+ ExperianDataQuality.DataQuality.Address.RefinementText = ExperianDataQuality.DataQuality.Address.RefinementText || 'Your selection covers a range of addresses. Enter your exact details:';
607
+ ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage = ExperianDataQuality.DataQuality.Address.ToManyMatchesMessage || 'Search cancelled (too many matches)';
608
+ ExperianDataQuality.DataQuality.Address.NoMatchesMessage = ExperianDataQuality.DataQuality.Address.NoMatchesMessage || 'No matches';
609
+ ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions = ExperianDataQuality.DataQuality.Address.PleaseSelectASuggestions || "Please select a suggestion.";
610
+ ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage = ExperianDataQuality.DataQuality.Address.PleaseEnterExactDetailsMessage || "Please enter exact details.";
611
+ ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage = ExperianDataQuality.DataQuality.Address.AddressOutsideOfRanageMessage || "This address is outside of the range. Please try again or click Back and select the correct range.";
skin/frontend/base/default/ExperianDataQuality/js/edqClient.js ADDED
@@ -0,0 +1,575 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var ExperianDataQuality = ExperianDataQuality || {};
2
+ ExperianDataQuality.DataQuality = ExperianDataQuality.DataQuality || {};
3
+ ExperianDataQuality.DataQuality.HtmlTags = ExperianDataQuality.DataQuality.HtmlTags || {};
4
+
5
+ //Configuration_Start
6
+ ExperianDataQuality.DataQuality.Configuration = function Configuration(inputMappings, outputMappings, type) {
7
+ this._inputMappings = inputMappings || [];
8
+ this._outputMappings = outputMappings || [];
9
+ this._type = type;
10
+ };
11
+
12
+ ExperianDataQuality.DataQuality.Configuration.prototype.addInputMapping = function addInputMapping(edqFieldName, htmlElementId) {
13
+ var sys = ExperianDataQuality.system;
14
+ var dq = ExperianDataQuality.DataQuality;
15
+
16
+ var mapping = this.getInputMappingByEdqFieldName(edqFieldName);
17
+ if (!sys.isNull(mapping)) {
18
+ mapping.addHtmlElementId(htmlElementId);
19
+ } else {
20
+ mapping = new dq.InputMapping(edqFieldName, htmlElementId);
21
+ this._inputMappings.push(mapping);
22
+ };
23
+ };
24
+
25
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementLabelFromInputMappingByEdqFieldName = function _getHtmlElementLabelFromInputMappingByEdqFieldName(edqFieldName) {
26
+ var sys = ExperianDataQuality.system;
27
+ var dq = ExperianDataQuality.DataQuality;
28
+
29
+ var htmlElement = this._getHtmlElementFromInputMappingByEdqFieldName(edqFieldName);
30
+ if (sys.isNull(htmlElement)) {
31
+ return undefined;
32
+ }
33
+
34
+ return sys.getElementLabelById(htmlElement.id);
35
+ };
36
+
37
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementFromInputMappingByEdqFieldName = function _getHtmlElementFromInputMappingByEdqFieldName(edqFieldName) {
38
+ var sys = ExperianDataQuality.system;
39
+ var dq = ExperianDataQuality.DataQuality;
40
+
41
+ var inputMapping = this.getInputMappingByEdqFieldName(edqFieldName);
42
+
43
+ if (sys.isNull(inputMapping) || inputMapping.htmlElementIds.length === 0) {
44
+ return undefined;
45
+ }
46
+
47
+ return sys.getElementById(inputMapping.htmlElementIds[0]);
48
+ };
49
+
50
+ ExperianDataQuality.DataQuality.Configuration.prototype._getHtmlElementsFromInputMappingByEdqFieldName = function _getHtmlElementsFromInputMappingByEdqFieldName(edqFieldName) {
51
+ var sys = ExperianDataQuality.system;
52
+ var dq = ExperianDataQuality.DataQuality;
53
+
54
+ var inputMapping = this.getInputMappingByEdqFieldName(edqFieldName);
55
+
56
+ if (sys.isNull(inputMapping) || inputMapping.htmlElementIds.length === 0) {
57
+ return undefined;
58
+ }
59
+
60
+ return inputMapping.htmlElementIds;
61
+ };
62
+
63
+ ExperianDataQuality.DataQuality.Configuration.prototype.getInputMappingByEdqFieldName = function getInputMappingByEdqFieldName(edqFieldName) {
64
+ var sys = ExperianDataQuality.system;
65
+
66
+ if (this._inputMappings.length === 0) {
67
+ return undefined;
68
+ }
69
+
70
+ for (var i = 0, max = this._inputMappings.length; i < max; i++) {
71
+ if (this._inputMappings[i].edqFieldName === edqFieldName) {
72
+ return this._inputMappings[i];
73
+ }
74
+ }
75
+ };
76
+
77
+ ExperianDataQuality.DataQuality.Configuration.prototype.addOutputMapping = function addOutputMapping(htmlElementId, edqFieldName) {
78
+ var sys = ExperianDataQuality.system;
79
+ var dq = ExperianDataQuality.DataQuality;
80
+
81
+ var mapping = this.getOutputMappingByHtmlElementId(htmlElementId);
82
+ if (!sys.isNull(mapping)) {
83
+ mapping.addEdqFieldName(edqFieldName);
84
+ } else {
85
+ mapping = new dq.OutputMapping(htmlElementId, edqFieldName);
86
+ this._outputMappings.push(mapping);
87
+ };
88
+ };
89
+
90
+ ExperianDataQuality.DataQuality.Configuration.prototype.getOutputMappingByHtmlElementId = function getOutputMappingByHtmlElementId(htmlElementId) {
91
+ var sys = ExperianDataQuality.system;
92
+
93
+ if (this._outputMappings.length === 0) {
94
+ return undefined;
95
+ }
96
+ for (var i = 0, max = this._outputMappings.length; i < max; i++) {
97
+ if (this._outputMappings[i].htmlElementId === htmlElementId) {
98
+ return this._outputMappings[i];
99
+ }
100
+ }
101
+ };
102
+
103
+ ExperianDataQuality.DataQuality.Configuration.prototype._getOutputMappingByEdqFieldName = function _getOutputMappingByEdqFieldName(edqFieldName) {
104
+ var sys = ExperianDataQuality.system;
105
+
106
+ if (this._outputMappings.length === 0) {
107
+ return undefined;
108
+ }
109
+
110
+ for (var i = 0, max = this._outputMappings.length; i < max; i++) {
111
+ for (var j = 0, total = this._outputMappings[i].edqFieldNames.length; j < total; j++) {
112
+ if (this._outputMappings[i].edqFieldNames[j] === edqFieldName) {
113
+ return this._outputMappings[i];
114
+ }
115
+ }
116
+ }
117
+
118
+ return undefined;
119
+ };
120
+ //Configuration_End
121
+
122
+ //Mapping_Start
123
+ ExperianDataQuality.DataQuality.InputMapping = function InputMapping(edqFieldName, htmlElementIdOrIds) {
124
+ var sys = ExperianDataQuality.system;
125
+
126
+ this.edqFieldName = edqFieldName;
127
+ if (sys.isArray(htmlElementIdOrIds)) {
128
+ this.htmlElementIds = htmlElementIdOrIds;
129
+ }
130
+ else {
131
+ this.htmlElementIds = new Array();
132
+
133
+ if(edqFieldName === 'Line4') {
134
+ this.htmlElementIds = [htmlElementIdOrIds];
135
+ }
136
+ else {
137
+ this.addHtmlElementId(htmlElementIdOrIds);
138
+ }
139
+ }
140
+ };
141
+
142
+ ExperianDataQuality.DataQuality.InputMapping.prototype.addHtmlElementId = function addHtmlElementId(htmlElementId) {
143
+ var sys = ExperianDataQuality.system;
144
+
145
+ if (sys.isNull(htmlElementId) || typeof htmlElementId !== "string") {
146
+ throw "Invalid htmlElementId value: " + htmlElementId;
147
+ }
148
+
149
+ if (!sys.contains(htmlElementId, this.htmlElementIds)) {
150
+ this.htmlElementIds = [htmlElementId];
151
+ }
152
+ };
153
+
154
+ ExperianDataQuality.DataQuality.OutputMapping = function OutputMapping(htmlElementId, edqFieldNameOrNames) {
155
+ var sys = ExperianDataQuality.system;
156
+
157
+ this.htmlElementId = htmlElementId;
158
+ if (sys.isArray(edqFieldNameOrNames)) {
159
+ this.edqFieldNames = edqFieldNameOrNames;
160
+ } else {
161
+ this.edqFieldNames = [];
162
+ this.addEdqFieldName(edqFieldNameOrNames);
163
+ };
164
+ };
165
+
166
+ ExperianDataQuality.DataQuality.OutputMapping.prototype.addEdqFieldName = function addEdqFieldName(edqFieldName) {
167
+ var sys = ExperianDataQuality.system;
168
+
169
+ if (sys.isNull(edqFieldName) || !sys.isString(edqFieldName)) {
170
+ throw "Invalid edqFieldName value. edqFieldName is either null, undefined or not a string";
171
+ }
172
+
173
+ if (!sys.contains(edqFieldName, this.edqFieldNames)) {
174
+ this.edqFieldNames.push(edqFieldName);
175
+ }
176
+ };
177
+ //Mapping_End
178
+
179
+ //Client_Start
180
+ ExperianDataQuality.DataQuality.Client = function Client(configurations) {
181
+ this._configurations = configurations || [];
182
+ };
183
+
184
+ ExperianDataQuality.DataQuality.Client.prototype.addConfiguration = function addConfiguration(configuration) {
185
+ var sys = ExperianDataQuality.system;
186
+
187
+ if (sys.isNull(configuration)) {
188
+ return;
189
+ }
190
+
191
+ if (!sys.contains(configuration, this._configurations)) {
192
+ this._configurations.push(configuration);
193
+ }
194
+ };
195
+
196
+ ExperianDataQuality.DataQuality.Client.prototype.initialize = function initialize() {
197
+ var sys = ExperianDataQuality.system;
198
+ var dq = ExperianDataQuality.DataQuality;
199
+
200
+ for (var i = 0, max = this._configurations.length; i < max; i++) {
201
+ this._initializeForConfiguration(this._configurations[i]);
202
+ }
203
+ };
204
+
205
+ ExperianDataQuality.DataQuality.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) { };
206
+
207
+ ExperianDataQuality.DataQuality.Client.prototype._hideAllInputMappingElementsExcept = function _hideAllInputMappingElementsExcept(inputMappings, edqFields) {
208
+ var sys = ExperianDataQuality.system;
209
+ var dq = ExperianDataQuality.DataQuality;
210
+
211
+ for (var j = 0, max = inputMappings.length; j < max; j++) {
212
+ var edqField = inputMappings[j].edqFieldName;
213
+
214
+ for(var k = 0, max2 = inputMappings[j].htmlElementIds.length; k < max2; k++) {
215
+
216
+ var showElement = sys.containsInArray(edqField, edqFields);
217
+
218
+ var elementId = inputMappings[j].htmlElementIds[k];
219
+
220
+ if(showElement === true) {
221
+ if(edqField === dq.BackButton) {
222
+ var backButtonIdSuffix = "";
223
+ if(sys.containsInArray(dq.Suggestions, edqFields)) {
224
+ backButtonIdSuffix = "suggestions";
225
+ } else if(sys.containsInArray(dq.TryAgain, edqFields)) {
226
+ backButtonIdSuffix = "tryagain";
227
+ } else if(sys.containsInArray(dq.NextButton, edqFields)) {
228
+ backButtonIdSuffix = "next";
229
+ }
230
+
231
+ if(backButtonIdSuffix !== "" && !sys.endsWith(backButtonIdSuffix, elementId)) {
232
+ showElement = false;
233
+ }
234
+ }
235
+ }
236
+
237
+ if (showElement) {
238
+ this._showElementAndLabel(elementId);
239
+ } else {
240
+ this._hideElementAndLabel(elementId);
241
+ }
242
+
243
+ }
244
+ }
245
+ };
246
+
247
+ ExperianDataQuality.DataQuality.Client.prototype._executeXMLHttpRequest = function _executeXMLHttpRequest(url, parameters, callback) {
248
+ var sys = ExperianDataQuality.system;
249
+
250
+ var xhr;
251
+
252
+ if(typeof XMLHttpRequest !== 'undefined') {
253
+ xhr = new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
254
+ } else {
255
+ var versions = ["MSXML2.XmlHttp.5.0",
256
+ "MSXML2.XmlHttp.4.0",
257
+ "MSXML2.XmlHttp.3.0",
258
+ "MSXML2.XmlHttp.2.0",
259
+ "Microsoft.XmlHttp"]; // code for IE6, IE5
260
+
261
+ for(var i = 0, max = versions.length; i < max; i++) {
262
+ try {
263
+ xhr = new ActiveXObject(versions[i]);
264
+ break;
265
+ } catch(e){
266
+ continue;
267
+ }
268
+ }
269
+ }
270
+
271
+ xhr.onreadystatechange = function ensureReadiness() {
272
+ if(xhr.readyState < 4 || xhr.status !== 200) {
273
+ if (xhr.status === 404)
274
+ {
275
+ callback('', xhr.statusText, xhr);
276
+ }
277
+ return;
278
+ }
279
+
280
+ if (xhr.readyState === 4) {
281
+ var response;
282
+ var errorMessage;
283
+
284
+ try {
285
+ response = JSON.parse(xhr.responseText);
286
+ errorMessage = response.error;
287
+ } catch (error) {
288
+ sys.logError(error);
289
+ errorMessage = "Invalid response";
290
+ }
291
+
292
+
293
+ callback(response, errorMessage, xhr);
294
+ }
295
+ };
296
+
297
+ xhr.open("POST", url, true);
298
+ xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
299
+ xhr.setRequestHeader('Accept', 'application/json, text/html, application/xml, text/xml, */*');
300
+ xhr.ontimeout = function () { callback('', 'Operation timed out.', xhr); };
301
+
302
+ var requestString = 'form_key' + '=' + window.FORM_KEY + '&';
303
+ for(parameter in parameters) {
304
+ requestString += parameter + '=' + encodeURIComponent(parameters[parameter]) + '&';
305
+ }
306
+
307
+ xhr.send(requestString);
308
+
309
+ if (xhr.status === 404)
310
+ {
311
+ callback('', xhr.statusText, xhr);
312
+ }
313
+ };
314
+
315
+ ExperianDataQuality.DataQuality.Client.prototype._showElementAndLabel = function _showElementAndLabel(elementId) {
316
+ this._executeActionOnElementAndLabel(elementId, ExperianDataQuality.DataQuality.Client.showElement);
317
+ };
318
+
319
+ ExperianDataQuality.DataQuality.Client.prototype._hideElementAndLabel = function _hideElementAndLabel(elementId) {
320
+ this._executeActionOnElementAndLabel(elementId, ExperianDataQuality.DataQuality.Client.hideElement);
321
+ };
322
+
323
+ ExperianDataQuality.DataQuality.Client.prototype._executeActionOnElementAndLabel = function _executeActionOnElementAndLabel(elementId, action) {
324
+ var sys = ExperianDataQuality.system;
325
+
326
+ var field = sys.getElementById(elementId);
327
+ if (!sys.isNull(field)) {
328
+ action(field);
329
+ }
330
+
331
+ var label = sys.getElementLabelById(elementId);
332
+ if(!sys.isNull(label)) {
333
+ action(label);
334
+ }
335
+ };
336
+
337
+ ExperianDataQuality.DataQuality.Client.prototype._handleErrorMessage = function _handleErrorMessage(configuration, edqFieldForMessage, message) {
338
+ var sys = ExperianDataQuality.system;
339
+ var dq = ExperianDataQuality.DataQuality;
340
+
341
+ var errorMessageLabelMapping = configuration._getOutputMappingByEdqFieldName(edqFieldForMessage);
342
+ if (!sys.isNullOrEmpty(errorMessageLabelMapping)) {
343
+ dq.Client._setValidationMessage(errorMessageLabelMapping.htmlElementId, message);
344
+ }
345
+ };
346
+
347
+ ExperianDataQuality.DataQuality.Client._setValidationMessage = function _setValidationMessage(textId, text) {
348
+ var sys = ExperianDataQuality.system;
349
+ var client = ExperianDataQuality.DataQuality.Client;
350
+
351
+ var validationMessageElement = sys.getElementById(textId);
352
+
353
+ if (!sys.isNull(validationMessageElement)) {
354
+ validationMessageElement.innerHTML = text;
355
+ validationMessageElement.style.display = sys.isNullOrEmpty(text) ? 'none' : 'inline';
356
+ }
357
+ };
358
+
359
+ ExperianDataQuality.DataQuality.Client.prototype.setValues = function setValues(result, configuration) {
360
+ var dq = ExperianDataQuality.DataQuality;
361
+ var sys = ExperianDataQuality.system;
362
+
363
+ if (!sys.isNull(result[dq.ErrorMessage])) { return; }
364
+
365
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
366
+ dq.Client._setValue(configuration._outputMappings[i], result, configuration._type);
367
+ }
368
+ };
369
+
370
+ ExperianDataQuality.DataQuality.Client._setValue = function _setValue(mapping, result, type) {
371
+ var sys = ExperianDataQuality.system;
372
+ var dq = ExperianDataQuality.DataQuality;
373
+
374
+ var client = dq.Client;
375
+
376
+ var val = '';
377
+ var edqFieldName = '';
378
+ for (var j = 0; j < mapping.edqFieldNames.length; j++) {
379
+ edqFieldName = mapping.edqFieldNames[j];
380
+ var fieldValue = result[edqFieldName];
381
+
382
+ if (sys.isNullOrEmpty(fieldValue)) {
383
+ continue;
384
+ };
385
+
386
+ if (val.length > 0) {
387
+ val += client.delimiter;
388
+ };
389
+
390
+ val += fieldValue;
391
+ }
392
+
393
+ if (edqFieldName === dq.Corrections) {
394
+ var returnMessage = sys.isNullOrEmpty(val) ? '' : '(Suggested: ' + val + ' )';
395
+ client._setValidationMessage(mapping.htmlElementId, returnMessage);
396
+ } else {
397
+ client.setElementValue(mapping.htmlElementId, val);
398
+ }
399
+ };
400
+ ExperianDataQuality.DataQuality.Client.delimiter = " ";
401
+
402
+ ExperianDataQuality.DataQuality.Client.setElementValue = function setElementValue(htmlElementId, value) {
403
+ var sys = ExperianDataQuality.system;
404
+
405
+ sys.setElementValue(htmlElementId, value);
406
+ };
407
+
408
+ ExperianDataQuality.DataQuality.Client.showElement = function showElement(element) {
409
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement(element, true);
410
+ };
411
+
412
+ ExperianDataQuality.DataQuality.Client.hideElement = function hideElement(element) {
413
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement(element, false);
414
+ };
415
+
416
+ ExperianDataQuality.DataQuality.Client._executeShowOrHideElementContainerOrElement = function _executeShowOrHideElementContainerOrElement(element, show) {
417
+ var dq = ExperianDataQuality.DataQuality;
418
+ var sys = ExperianDataQuality.system;
419
+ var client = dq.Client;
420
+
421
+ if (sys.isNull(element)) {
422
+ return;
423
+ }
424
+
425
+ if(element.tagName === dq.HtmlTags.Input && !show && element.id.match(/-edq-/) !== null) {
426
+ element.value = '';
427
+ }
428
+
429
+ if(element.tagName === dq.HtmlTags.Label || element.tagName === dq.HtmlTags.Div) {
430
+ element.style.display = show ? "" : "none";
431
+ }
432
+
433
+ var container = client._tryGetElementContainer(element);
434
+ if(!sys.isNull(container)) {
435
+ container.style.display = show ? "" : "none";
436
+ return;
437
+ }
438
+
439
+ element.style.display = show ? "" : "none";
440
+ };
441
+
442
+ ExperianDataQuality.DataQuality.Client._tryGetElementContainer = function _tryGetElementContainer(element) {
443
+ var client = ExperianDataQuality.DataQuality.Client;
444
+ var sys = ExperianDataQuality.system;
445
+
446
+ var parentNodeOfElement = element.parentNode;
447
+ var classesOfElement = parentNodeOfElement.className;
448
+
449
+ while(ExperianDataQuality.DataQuality.HtmlTags.ListItem !== parentNodeOfElement.nodeName)
450
+ {
451
+ if(( ExperianDataQuality.DataQuality.HtmlTags.Div === parentNodeOfElement.nodeName && classesOfElement.match(/edq_wrapper/) !== null))
452
+ {
453
+ break;
454
+ }
455
+
456
+ parentNodeOfElement = parentNodeOfElement.parentNode;
457
+ classesOfElement = parentNodeOfElement.className;
458
+ }
459
+
460
+ if (client._isContainerElement(parentNodeOfElement)) {
461
+ return parentNodeOfElement;
462
+ }
463
+
464
+ return undefined;
465
+ };
466
+
467
+ ExperianDataQuality.DataQuality.Client._isContainerElement = function _isContainerElement(element){
468
+ var dq = ExperianDataQuality.DataQuality;
469
+
470
+ if ((element.tagName === dq.HtmlTags.Div
471
+ || element.tagName === dq.HtmlTags.ListItem
472
+ || element.tagName === dq.HtmlTags.Span
473
+ || element.tagName === dq.HtmlTags.TableHeader
474
+ || element.tagName === dq.HtmlTags.TableData
475
+ || element.tagName === dq.HtmlTags.TableRow)) {
476
+ return true;
477
+ }
478
+
479
+ return false;
480
+ };
481
+
482
+ ExperianDataQuality.DataQuality.Client.collectValuesFromInputMapping = function collectValuesFromInputMapping(inputMapping) {
483
+ var sys = ExperianDataQuality.system;
484
+
485
+ value = '';
486
+ for (var i = 0, max = inputMapping.htmlElementIds.length; i < max; i++) {
487
+ var htmlElement = sys.getElementById(inputMapping.htmlElementIds[i]);
488
+
489
+ if (!sys.isNull(htmlElement) && !sys.isNullOrEmpty(htmlElement.value)) {
490
+ value += htmlElement.value + ' ';
491
+ }
492
+ }
493
+
494
+ return value.trim();
495
+ };
496
+
497
+ //Client_End
498
+ ExperianDataQuality.DataQuality.Active = 'Active';
499
+ ExperianDataQuality.DataQuality.Deactive = 'Deactive';
500
+ ExperianDataQuality.DataQuality.ManualEntryState = ExperianDataQuality.DataQuality.Deactive;
501
+
502
+ ExperianDataQuality.DataQuality.ConfigurationType = { Address: 3 };
503
+ ExperianDataQuality.DataQuality.WorkFlowStages = { Input: 0, Suggestions: 1, Refining: 2, Verified: 3 };
504
+
505
+ ExperianDataQuality.DataQuality.Number = 'Number';
506
+ ExperianDataQuality.DataQuality.AreaCode = 'DefaultCountryCode';
507
+ ExperianDataQuality.DataQuality.EmailAddress = 'EmailAddress';
508
+ ExperianDataQuality.DataQuality.Message = 'Message';
509
+ ExperianDataQuality.DataQuality.Certainty = 'Certainty';
510
+ ExperianDataQuality.DataQuality.Loader = 'Loader';
511
+ ExperianDataQuality.DataQuality.ErrorMessage = 'ErrorMessage';
512
+ ExperianDataQuality.DataQuality.ValidationStatusVerified = 'Verified';
513
+ ExperianDataQuality.DataQuality.ValidationStatusNotVerified = 'Not verified';
514
+ ExperianDataQuality.DataQuality.ValidationStatus = 'ValidationStatus';
515
+ ExperianDataQuality.DataQuality.Country = 'Country';
516
+ ExperianDataQuality.DataQuality.PhoneCountry = 'PhoneCountry';
517
+ ExperianDataQuality.DataQuality.Suggested = 'Suggested';
518
+ ExperianDataQuality.DataQuality.Corrections = 'Corrections';
519
+
520
+ ExperianDataQuality.DataQuality.DataSet = 'DataSet';
521
+ ExperianDataQuality.DataQuality.Street = 'Street1';
522
+ ExperianDataQuality.DataQuality.City = 'City';
523
+ ExperianDataQuality.DataQuality.StreetNumber = 'StreetNumber';
524
+ ExperianDataQuality.DataQuality.Postcode = 'Postcode';
525
+ ExperianDataQuality.DataQuality.State = 'State';
526
+ ExperianDataQuality.DataQuality.BuildingNumber = 'BuildingNumberOrName';
527
+ ExperianDataQuality.DataQuality.Town = 'Town';
528
+ ExperianDataQuality.DataQuality.FindAddressButton = 'FindAddressButton';
529
+ ExperianDataQuality.DataQuality.ChangeAddressButton = 'ChangeAddressButton';
530
+ ExperianDataQuality.DataQuality.BackButton = 'BackButton';
531
+ ExperianDataQuality.DataQuality.SelectButton = 'SelectButton';
532
+ ExperianDataQuality.DataQuality.NextButton = 'NextButton';
533
+ ExperianDataQuality.DataQuality.Suggestions = 'Suggestions';
534
+ ExperianDataQuality.DataQuality.UnknownPostCode = 'UnknownPostCode';
535
+ ExperianDataQuality.DataQuality.KnownPostCode = 'KnownPostCode';
536
+ ExperianDataQuality.DataQuality.RefineInput = 'Refinement';
537
+ ExperianDataQuality.DataQuality.ManualEntry = 'ManualEntry';
538
+ ExperianDataQuality.DataQuality.TryAgain = 'TryAgain';
539
+ ExperianDataQuality.DataQuality.Moniker = 'Moniker';
540
+ ExperianDataQuality.DataQuality.Layout = 'Layout';
541
+ ExperianDataQuality.DataQuality.PickList = 'PickList';
542
+
543
+ ExperianDataQuality.DataQuality.Line1 = 'Line0';
544
+ ExperianDataQuality.DataQuality.Line2 = 'Line1';
545
+ ExperianDataQuality.DataQuality.Line3 = 'Line2';
546
+ ExperianDataQuality.DataQuality.Line4 = 'Line3';
547
+ ExperianDataQuality.DataQuality.Line5 = 'Line4';
548
+ ExperianDataQuality.DataQuality.Line6 = 'Line5';
549
+
550
+ ExperianDataQuality.DataQuality.HtmlTags.Span = 'SPAN';
551
+ ExperianDataQuality.DataQuality.HtmlTags.Div = 'DIV';
552
+ ExperianDataQuality.DataQuality.HtmlTags.ListItem = 'LI';
553
+ ExperianDataQuality.DataQuality.HtmlTags.TableHeader = 'TH';
554
+ ExperianDataQuality.DataQuality.HtmlTags.TableData = 'TD';
555
+ ExperianDataQuality.DataQuality.HtmlTags.TableRow = 'TR';
556
+ ExperianDataQuality.DataQuality.HtmlTags.Select = 'SELECT';
557
+ ExperianDataQuality.DataQuality.HtmlTags.Label = 'LABEL';
558
+ ExperianDataQuality.DataQuality.HtmlTags.Button = 'BUTTON';
559
+ ExperianDataQuality.DataQuality.HtmlTags.Link = 'A';
560
+ ExperianDataQuality.DataQuality.HtmlTags.Option = 'OPTION';
561
+ ExperianDataQuality.DataQuality.HtmlTags.Input = 'INPUT';
562
+
563
+ ExperianDataQuality.DataQuality.Snapshot = {
564
+ 'Line0' : '',
565
+ 'Line1' : '',
566
+ 'Line2' : '',
567
+ 'Line3' : '',
568
+ 'Line4' : '',
569
+ //'DataSet' : '',
570
+ 'Street1' : '',
571
+ 'City' : '',
572
+ 'Postcode' : '',
573
+ 'State' : '',
574
+ 'BuildingNumberOrName' : ''
575
+ };
skin/frontend/base/default/ExperianDataQuality/js/json2.js ADDED
@@ -0,0 +1,480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ http://www.JSON.org/json2.js
3
+ 2011-02-23
4
+
5
+ Public Domain.
6
+
7
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8
+
9
+ See http://www.JSON.org/js.html
10
+
11
+
12
+ This code should be minified before deployment.
13
+ See http://javascript.crockford.com/jsmin.html
14
+
15
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16
+ NOT CONTROL.
17
+
18
+
19
+ This file creates a global JSON object containing two methods: stringify
20
+ and parse.
21
+
22
+ JSON.stringify(value, replacer, space)
23
+ value any JavaScript value, usually an object or array.
24
+
25
+ replacer an optional parameter that determines how object
26
+ values are stringified for objects. It can be a
27
+ function or an array of strings.
28
+
29
+ space an optional parameter that specifies the indentation
30
+ of nested structures. If it is omitted, the text will
31
+ be packed without extra whitespace. If it is a number,
32
+ it will specify the number of spaces to indent at each
33
+ level. If it is a string (such as '\t' or '&nbsp;'),
34
+ it contains the characters used to indent at each level.
35
+
36
+ This method produces a JSON text from a JavaScript value.
37
+
38
+ When an object value is found, if the object contains a toJSON
39
+ method, its toJSON method will be called and the result will be
40
+ stringified. A toJSON method does not serialize: it returns the
41
+ value represented by the name/value pair that should be serialized,
42
+ or undefined if nothing should be serialized. The toJSON method
43
+ will be passed the key associated with the value, and this will be
44
+ bound to the value
45
+
46
+ For example, this would serialize Dates as ISO strings.
47
+
48
+ Date.prototype.toJSON = function (key) {
49
+ function f(n) {
50
+ // Format integers to have at least two digits.
51
+ return n < 10 ? '0' + n : n;
52
+ }
53
+
54
+ return this.getUTCFullYear() + '-' +
55
+ f(this.getUTCMonth() + 1) + '-' +
56
+ f(this.getUTCDate()) + 'T' +
57
+ f(this.getUTCHours()) + ':' +
58
+ f(this.getUTCMinutes()) + ':' +
59
+ f(this.getUTCSeconds()) + 'Z';
60
+ };
61
+
62
+ You can provide an optional replacer method. It will be passed the
63
+ key and value of each member, with this bound to the containing
64
+ object. The value that is returned from your method will be
65
+ serialized. If your method returns undefined, then the member will
66
+ be excluded from the serialization.
67
+
68
+ If the replacer parameter is an array of strings, then it will be
69
+ used to select the members to be serialized. It filters the results
70
+ such that only members with keys listed in the replacer array are
71
+ stringified.
72
+
73
+ Values that do not have JSON representations, such as undefined or
74
+ functions, will not be serialized. Such values in objects will be
75
+ dropped; in arrays they will be replaced with null. You can use
76
+ a replacer function to replace those with JSON values.
77
+ JSON.stringify(undefined) returns undefined.
78
+
79
+ The optional space parameter produces a stringification of the
80
+ value that is filled with line breaks and indentation to make it
81
+ easier to read.
82
+
83
+ If the space parameter is a non-empty string, then that string will
84
+ be used for indentation. If the space parameter is a number, then
85
+ the indentation will be that many spaces.
86
+
87
+ Example:
88
+
89
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
90
+ // text is '["e",{"pluribus":"unum"}]'
91
+
92
+
93
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95
+
96
+ text = JSON.stringify([new Date()], function (key, value) {
97
+ return this[key] instanceof Date ?
98
+ 'Date(' + this[key] + ')' : value;
99
+ });
100
+ // text is '["Date(---current time---)"]'
101
+
102
+
103
+ JSON.parse(text, reviver)
104
+ This method parses a JSON text to produce an object or array.
105
+ It can throw a SyntaxError exception.
106
+
107
+ The optional reviver parameter is a function that can filter and
108
+ transform the results. It receives each of the keys and values,
109
+ and its return value is used instead of the original value.
110
+ If it returns what it received, then the structure is not modified.
111
+ If it returns undefined then the member is deleted.
112
+
113
+ Example:
114
+
115
+ // Parse the text. Values that look like ISO date strings will
116
+ // be converted to Date objects.
117
+
118
+ myData = JSON.parse(text, function (key, value) {
119
+ var a;
120
+ if (typeof value === 'string') {
121
+ a =
122
+ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123
+ if (a) {
124
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125
+ +a[5], +a[6]));
126
+ }
127
+ }
128
+ return value;
129
+ });
130
+
131
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132
+ var d;
133
+ if (typeof value === 'string' &&
134
+ value.slice(0, 5) === 'Date(' &&
135
+ value.slice(-1) === ')') {
136
+ d = new Date(value.slice(5, -1));
137
+ if (d) {
138
+ return d;
139
+ }
140
+ }
141
+ return value;
142
+ });
143
+
144
+
145
+ This is a reference implementation. You are free to copy, modify, or
146
+ redistribute.
147
+ */
148
+
149
+ /*jslint evil: true, strict: false, regexp: false */
150
+
151
+ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
155
+ test, toJSON, toString, valueOf
156
+ */
157
+
158
+
159
+ // Create a JSON object only if one does not already exist. We create the
160
+ // methods in a closure to avoid creating global variables.
161
+
162
+ var JSON;
163
+ if (!JSON) {
164
+ JSON = {};
165
+ }
166
+
167
+ (function () {
168
+ "use strict";
169
+
170
+ function f(n) {
171
+ // Format integers to have at least two digits.
172
+ return n < 10 ? '0' + n : n;
173
+ }
174
+
175
+ if (typeof Date.prototype.toJSON !== 'function') {
176
+
177
+ Date.prototype.toJSON = function (key) {
178
+
179
+ return isFinite(this.valueOf()) ?
180
+ this.getUTCFullYear() + '-' +
181
+ f(this.getUTCMonth() + 1) + '-' +
182
+ f(this.getUTCDate()) + 'T' +
183
+ f(this.getUTCHours()) + ':' +
184
+ f(this.getUTCMinutes()) + ':' +
185
+ f(this.getUTCSeconds()) + 'Z' : null;
186
+ };
187
+
188
+ String.prototype.toJSON =
189
+ Number.prototype.toJSON =
190
+ Boolean.prototype.toJSON = function (key) {
191
+ return this.valueOf();
192
+ };
193
+ }
194
+
195
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
196
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
197
+ gap,
198
+ indent,
199
+ meta = { // table of character substitutions
200
+ '\b': '\\b',
201
+ '\t': '\\t',
202
+ '\n': '\\n',
203
+ '\f': '\\f',
204
+ '\r': '\\r',
205
+ '"' : '\\"',
206
+ '\\': '\\\\'
207
+ },
208
+ rep;
209
+
210
+
211
+ function quote(string) {
212
+
213
+ // If the string contains no control characters, no quote characters, and no
214
+ // backslash characters, then we can safely slap some quotes around it.
215
+ // Otherwise we must also replace the offending characters with safe escape
216
+ // sequences.
217
+
218
+ escapable.lastIndex = 0;
219
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220
+ var c = meta[a];
221
+ return typeof c === 'string' ? c :
222
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
223
+ }) + '"' : '"' + string + '"';
224
+ }
225
+
226
+
227
+ function str(key, holder) {
228
+
229
+ // Produce a string from holder[key].
230
+
231
+ var i, // The loop counter.
232
+ k, // The member key.
233
+ v, // The member value.
234
+ length,
235
+ mind = gap,
236
+ partial,
237
+ value = holder[key];
238
+
239
+ // If the value has a toJSON method, call it to obtain a replacement value.
240
+
241
+ if (value && typeof value === 'object' &&
242
+ typeof value.toJSON === 'function') {
243
+ value = value.toJSON(key);
244
+ }
245
+
246
+ // If we were called with a replacer function, then call the replacer to
247
+ // obtain a replacement value.
248
+
249
+ if (typeof rep === 'function') {
250
+ value = rep.call(holder, key, value);
251
+ }
252
+
253
+ // What happens next depends on the value's type.
254
+
255
+ switch (typeof value) {
256
+ case 'string':
257
+ return quote(value);
258
+
259
+ case 'number':
260
+
261
+ // JSON numbers must be finite. Encode non-finite numbers as null.
262
+
263
+ return isFinite(value) ? String(value) : 'null';
264
+
265
+ case 'boolean':
266
+ case 'null':
267
+
268
+ // If the value is a boolean or null, convert it to a string. Note:
269
+ // typeof null does not produce 'null'. The case is included here in
270
+ // the remote chance that this gets fixed someday.
271
+
272
+ return String(value);
273
+
274
+ // If the type is 'object', we might be dealing with an object or an array or
275
+ // null.
276
+
277
+ case 'object':
278
+
279
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
280
+ // so watch out for that case.
281
+
282
+ if (!value) {
283
+ return 'null';
284
+ }
285
+
286
+ // Make an array to hold the partial results of stringifying this object value.
287
+
288
+ gap += indent;
289
+ partial = [];
290
+
291
+ // Is the value an array?
292
+
293
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
294
+
295
+ // The value is an array. Stringify every element. Use null as a placeholder
296
+ // for non-JSON values.
297
+
298
+ length = value.length;
299
+ for (i = 0; i < length; i += 1) {
300
+ partial[i] = str(i, value) || 'null';
301
+ }
302
+
303
+ // Join all of the elements together, separated with commas, and wrap them in
304
+ // brackets.
305
+
306
+ v = partial.length === 0 ? '[]' : gap ?
307
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
308
+ '[' + partial.join(',') + ']';
309
+ gap = mind;
310
+ return v;
311
+ }
312
+
313
+ // If the replacer is an array, use it to select the members to be stringified.
314
+
315
+ if (rep && typeof rep === 'object') {
316
+ length = rep.length;
317
+ for (i = 0; i < length; i += 1) {
318
+ if (typeof rep[i] === 'string') {
319
+ k = rep[i];
320
+ v = str(k, value);
321
+ if (v) {
322
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
323
+ }
324
+ }
325
+ }
326
+ } else {
327
+
328
+ // Otherwise, iterate through all of the keys in the object.
329
+
330
+ for (k in value) {
331
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
332
+ v = str(k, value);
333
+ if (v) {
334
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ // Join all of the member texts together, separated with commas,
341
+ // and wrap them in braces.
342
+
343
+ v = partial.length === 0 ? '{}' : gap ?
344
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
345
+ '{' + partial.join(',') + '}';
346
+ gap = mind;
347
+ return v;
348
+ }
349
+ }
350
+
351
+ // If the JSON object does not yet have a stringify method, give it one.
352
+
353
+ if (typeof JSON.stringify !== 'function') {
354
+ JSON.stringify = function (value, replacer, space) {
355
+
356
+ // The stringify method takes a value and an optional replacer, and an optional
357
+ // space parameter, and returns a JSON text. The replacer can be a function
358
+ // that can replace values, or an array of strings that will select the keys.
359
+ // A default replacer method can be provided. Use of the space parameter can
360
+ // produce text that is more easily readable.
361
+
362
+ var i;
363
+ gap = '';
364
+ indent = '';
365
+
366
+ // If the space parameter is a number, make an indent string containing that
367
+ // many spaces.
368
+
369
+ if (typeof space === 'number') {
370
+ for (i = 0; i < space; i += 1) {
371
+ indent += ' ';
372
+ }
373
+
374
+ // If the space parameter is a string, it will be used as the indent string.
375
+
376
+ } else if (typeof space === 'string') {
377
+ indent = space;
378
+ }
379
+
380
+ // If there is a replacer, it must be a function or an array.
381
+ // Otherwise, throw an error.
382
+
383
+ rep = replacer;
384
+ if (replacer && typeof replacer !== 'function' &&
385
+ (typeof replacer !== 'object' ||
386
+ typeof replacer.length !== 'number')) {
387
+ throw new Error('JSON.stringify');
388
+ }
389
+
390
+ // Make a fake root object containing our value under the key of ''.
391
+ // Return the result of stringifying the value.
392
+
393
+ return str('', {'': value});
394
+ };
395
+ }
396
+
397
+
398
+ // If the JSON object does not yet have a parse method, give it one.
399
+
400
+ if (typeof JSON.parse !== 'function') {
401
+ JSON.parse = function (text, reviver) {
402
+
403
+ // The parse method takes a text and an optional reviver function, and returns
404
+ // a JavaScript value if the text is a valid JSON text.
405
+
406
+ var j;
407
+
408
+ function walk(holder, key) {
409
+
410
+ // The walk method is used to recursively walk the resulting structure so
411
+ // that modifications can be made.
412
+
413
+ var k, v, value = holder[key];
414
+ if (value && typeof value === 'object') {
415
+ for (k in value) {
416
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
417
+ v = walk(value, k);
418
+ if (v !== undefined) {
419
+ value[k] = v;
420
+ } else {
421
+ delete value[k];
422
+ }
423
+ }
424
+ }
425
+ }
426
+ return reviver.call(holder, key, value);
427
+ }
428
+
429
+
430
+ // Parsing happens in four stages. In the first stage, we replace certain
431
+ // Unicode characters with escape sequences. JavaScript handles many characters
432
+ // incorrectly, either silently deleting them, or treating them as line endings.
433
+
434
+ text = String(text);
435
+ cx.lastIndex = 0;
436
+ if (cx.test(text)) {
437
+ text = text.replace(cx, function (a) {
438
+ return '\\u' +
439
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
440
+ });
441
+ }
442
+
443
+ // In the second stage, we run the text against regular expressions that look
444
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
445
+ // because they can cause invocation, and '=' because it can cause mutation.
446
+ // But just to be safe, we want to reject all unexpected forms.
447
+
448
+ // We split the second stage into 4 regexp operations in order to work around
449
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
450
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
451
+ // replace all simple value tokens with ']' characters. Third, we delete all
452
+ // open brackets that follow a colon or comma or that begin the text. Finally,
453
+ // we look to see that the remaining characters are only whitespace or ']' or
454
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
455
+
456
+ if (/^[\],:{}\s]*$/
457
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
458
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
459
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
460
+
461
+ // In the third stage we use the eval function to compile the text into a
462
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
463
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
464
+ // in parens to eliminate the ambiguity.
465
+
466
+ j = eval('(' + text + ')');
467
+
468
+ // In the optional fourth stage, we recursively walk the new structure, passing
469
+ // each name/value pair to a reviver function for possible transformation.
470
+
471
+ return typeof reviver === 'function' ?
472
+ walk({'': j}, '') : j;
473
+ }
474
+
475
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
476
+
477
+ throw new SyntaxError('JSON.parse');
478
+ };
479
+ }
480
+ }());
skin/frontend/base/default/ExperianDataQuality/js/system.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var ExperianDataQuality = ExperianDataQuality || {};
2
+ ExperianDataQuality.system = ExperianDataQuality.system || {};
3
+
4
+ ExperianDataQuality.system.isString = function isString(value) { return typeof value === "string"; };
5
+ ExperianDataQuality.system.isUndefined = function isUndefined(value) { return typeof(value) === "undefined"; };
6
+ ExperianDataQuality.system.isNull = function isNull(value) { return ExperianDataQuality.system.isUndefined(value) || value === null; };
7
+ ExperianDataQuality.system.isNullOrEmpty = function isNullOrEmpty(str) { return ExperianDataQuality.system.isNull(str) || str === ""; };
8
+ ExperianDataQuality.system.isFunction = function isFunction(obj) { return !ExperianDataQuality.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Function]'; };
9
+ ExperianDataQuality.system.isArray = function isArray(obj) { return !ExperianDataQuality.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Array]'; };
10
+ ExperianDataQuality.system.logError = function logError(obj) {
11
+ if (window.console) {
12
+ window.console.log(obj);
13
+ } else { //IE does not have a logger.
14
+ //alert(obj);
15
+ };
16
+ };
17
+
18
+ ExperianDataQuality.system.containsInArray = function containsInArray(needle, haystack) {
19
+ if (haystack.indexOf(needle) !== -1) {
20
+ return true;
21
+ }
22
+ return false;
23
+ };
24
+
25
+ ExperianDataQuality.system.contains = function contains(needle, haystack) {
26
+ if (typeof haystack[needle] === 'undefined') {
27
+ return false;
28
+ }
29
+ return true;
30
+ };
31
+
32
+ ExperianDataQuality.system.getElementValue = function getElementValue(htmlElementId) {
33
+ var htmlElement = this.getElementById(htmlElementId);
34
+ if (this.isNull(htmlElement)) {
35
+ return undefined;
36
+ }
37
+
38
+ return htmlElement.value;
39
+ };
40
+
41
+ ExperianDataQuality.system.setElementValue = function setElementValue(htmlElementId, value) {
42
+ var htmlElement = this.getElementById(htmlElementId);
43
+ if (this.isNull(htmlElement)) {
44
+ return;
45
+ }
46
+
47
+ if (htmlElement.tagName === "LABEL") {
48
+ htmlElement.innerHTML = value;
49
+ } else {
50
+ htmlElement.value = value;
51
+ }
52
+ };
53
+
54
+ ExperianDataQuality.system.getElementById = function getElementById(selector) {
55
+ return document.getElementById(selector);
56
+ };
57
+
58
+ ExperianDataQuality.system.getElementLabelById = function getElementLabelById(htmlElementId) {
59
+ var labels = document.getElementsByTagName('Label');
60
+
61
+ for (var i = 0, max = labels.length; i < max; i++) {
62
+ if(!this.isNull(labels[i].attributes['for'])) {
63
+ if(labels[i].attributes['for'].value === htmlElementId) {
64
+ return labels[i];
65
+ }
66
+ }
67
+ }
68
+
69
+ return undefined;
70
+ };
71
+
72
+ ExperianDataQuality.system.toBoolean = function toBoolean(value) {
73
+ if (value.toString().toUpperCase() === 'TRUE' || value.toString() === '1') {
74
+ return true;
75
+ }
76
+ return false;
77
+ };
78
+
79
+ ExperianDataQuality.system.beginsWith = function beginsWith(needle, haystack) {
80
+ return (haystack.substr(0, needle.length) === needle);
81
+ };
82
+
83
+ ExperianDataQuality.system.endsWith = function endsWith(needle, haystack) {
84
+ return haystack.indexOf(needle, haystack.length - needle.length) !== -1;
85
+ };
86
+
87
+ ExperianDataQuality.system.removeSpecialCharacters = function removeSpecialCharacters(value) {
88
+ return value.replace(/[^\d.]/g, "");
89
+ };
90
+
91
+ ExperianDataQuality.system.inherit = (function () {
92
+ var F = function (){};
93
+ return function (C, P) {
94
+ F.prototype = P.prototype;
95
+ C.prototype = new F();
96
+ C.uber = P.prototype;
97
+ C.prototype.constructor = C;
98
+ };
99
+ }());
100
+
101
+ if (Array && !Array.indexOf){
102
+ Array.prototype.indexOf = function (elt /*, from*/) {
103
+ var len = this.length;
104
+
105
+ var from = Number(arguments[1]) || 0;
106
+ from = (from < 0)? Math.ceil(from) : Math.floor(from);
107
+ if (from < 0) { from += len; }
108
+ for (; from < len; from++) {
109
+ if (from in this && this[from] === elt) { return from;}
110
+ }
111
+ return -1;
112
+ };
113
+ };
114
+
115
+ if(typeof String.prototype.trim !== 'function') {
116
+ String.prototype.trim = function() {
117
+ return this.replace(/^\s+|\s+$/g, '');
118
+ };
119
+ };
skin/frontend/base/default/edq/images/opc-ajax-loader.gif ADDED
Binary file
skin/frontend/base/default/edq/js/edqClient.js ADDED
@@ -0,0 +1,526 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var EDQ = EDQ || {};
2
+ EDQ.DataQuality = EDQ.DataQuality || {};
3
+
4
+ //Configuration_Start
5
+ EDQ.DataQuality.Configuration = function Configuration(outputMappings, inputMappings, type) {
6
+ var dq = EDQ.DataQuality;
7
+
8
+ this._inputMappings = inputMappings || [];
9
+ this._outputMappings = outputMappings || [];
10
+ this.type = type;
11
+ };
12
+
13
+ EDQ.DataQuality.Configuration.prototype.addOutputMapping = function addOutputMapping(htmlFieldId, edqFieldName) {
14
+ var dq = EDQ.DataQuality;
15
+ var sys = EDQ.system;
16
+
17
+ var mapping = this.getOutputMappingByElementId(htmlFieldId);
18
+ if (!sys.isNull(mapping)) {
19
+ mapping.addEDQFieldName(edqFieldName);
20
+ } else {
21
+ mapping = new dq.OutputMapping(htmlFieldId, edqFieldName);
22
+ this._outputMappings.push(mapping);
23
+ };
24
+ };
25
+
26
+ EDQ.DataQuality.Configuration.prototype.getOutputMappingByElementId = function getOutputMappingByElementId(htmlFieldId) {
27
+ var sys = EDQ.system;
28
+
29
+ if (sys.isNull(this._outputMappings) || this._outputMappings.length === 0) {
30
+ return null;
31
+ }
32
+
33
+ for (var i = 0; i < this._outputMappings.length; i++) {
34
+ if (this._outputMappings[i].htmlFieldId === htmlFieldId) {
35
+ return this._outputMappings[i];
36
+ }
37
+ }
38
+ };
39
+
40
+ EDQ.DataQuality.Configuration.prototype._getOutputMappingByEdqFieldName = function _getOutputMappingByEdqFieldName(edqFieldName) {
41
+ var sys = EDQ.system;
42
+
43
+ if (sys.isNull(this._outputMappings) || this._outputMappings.length === 0) {
44
+ return null;
45
+ }
46
+
47
+ for (var i = 0; i < this._outputMappings.length; i++) {
48
+ for (var j = 0; j < this._outputMappings[i].edqFieldNames.length; j++) {
49
+ if (this._outputMappings[i].edqFieldNames[j] === edqFieldName) {
50
+ return this._outputMappings[i];
51
+ }
52
+ }
53
+ }
54
+
55
+ return null;
56
+ };
57
+
58
+ EDQ.DataQuality.Configuration.prototype.addInputMapping = function addInputMapping(edqFieldName, htmlFieldId) {
59
+ var dq = EDQ.DataQuality;
60
+ var sys = EDQ.system;
61
+
62
+ var mapping = this.getInputMappingByEdqFieldName(edqFieldName);
63
+ if (!sys.isNull(mapping)) {
64
+ mapping.addHtmlFieldId(htmlFieldId);
65
+ } else {
66
+ mapping = new dq.InputMapping(edqFieldName, htmlFieldId);
67
+ this._inputMappings.push(mapping);
68
+ };
69
+ };
70
+
71
+ EDQ.DataQuality.Configuration.prototype.getInputMappingByEdqFieldName = function getInputMappingByEdqFieldName(edqFieldName) {
72
+ var sys = EDQ.system;
73
+
74
+ if (sys.isNull(this._inputMappings) || this._inputMappings.length === 0) {
75
+ return null;
76
+ }
77
+
78
+ for (var i = 0; i < this._inputMappings.length; i++) {
79
+ if (this._inputMappings[i].edqFieldName === edqFieldName) {
80
+ return this._inputMappings[i];
81
+ }
82
+ }
83
+ };
84
+ //Configuration_End
85
+
86
+ //Mapping_Start
87
+ EDQ.DataQuality.OutputMapping = function OutputMapping(htmlFieldId, edqFieldName) {
88
+ this.htmlFieldId = htmlFieldId;
89
+ this.edqFieldNames = [];
90
+ this.addEDQFieldName(edqFieldName);
91
+ };
92
+
93
+ EDQ.DataQuality.OutputMapping.prototype.addEDQFieldName = function addEDQFieldName(edqFieldName) {
94
+ var sys = EDQ.system;
95
+
96
+ if (sys.isNull(edqFieldName) || typeof edqFieldName !== "string") { throw "Invalid edqFieldName value: " + edqFieldName; }
97
+
98
+ this.edqFieldNames.push(edqFieldName);
99
+ };
100
+
101
+ EDQ.DataQuality.InputMapping = function InputMapping(edqFieldName, htmlFieldId) {
102
+ this.edqFieldName = edqFieldName;
103
+ this.htmlFieldIds = [];
104
+ this.addHtmlFieldId(htmlFieldId);
105
+ };
106
+
107
+ EDQ.DataQuality.InputMapping.prototype.addHtmlFieldId = function addHtmlFieldId(htmlFieldId) {
108
+ var sys = EDQ.system;
109
+
110
+ if (sys.isNull(htmlFieldId) || typeof htmlFieldId !== "string") { throw "Invalid htmlFieldId value: " + htmlFieldId; }
111
+
112
+ this.htmlFieldIds.push(htmlFieldId);
113
+ };
114
+ //Mapping_End
115
+
116
+ //Client_Start
117
+ EDQ.DataQuality.Client = function Client(configurations, settings) {
118
+ var sys = EDQ.system;
119
+ var dq = EDQ.DataQuality;
120
+
121
+ settings = settings || {};
122
+ this.phoneServiceUrl = settings.phoneUrl || '';
123
+ this.emailServiceUrl = settings.emailUrl || '';
124
+ this.serviceUrl = settings.url || '';
125
+ this.emailValidationKey = settings.emailValidationKey || '';
126
+ this.phoneValidationKey = settings.phoneValidationKey || '';
127
+ this.fadeoutValidationMessageTimeout = settings.fadeoutValidationMessageTimeout || 1000;
128
+ this.defaultCountry = settings.defaultCountry || 'USA';
129
+ this.delimiter = settings.delimiter || ', ';
130
+ this._configurations = configurations;
131
+ this._token = settings.token || '';
132
+ };
133
+ EDQ.DataQuality.Client.prototype.initialize = function initialize() {
134
+ var sys = EDQ.system;
135
+
136
+ if (sys.isNull(this._configurations)) { return; }
137
+
138
+ for (var i = 0; i < this._configurations.length; i++) {
139
+ this._initializeForConfiguration(this._configurations[i]);
140
+ }
141
+ };
142
+
143
+ EDQ.DataQuality.Client.prototype._initializeForConfiguration = function _initializeForConfiguration(configuration) {
144
+ var dq = EDQ.DataQuality;
145
+ var sys = EDQ.system;
146
+
147
+ var client = this;
148
+ var elementIds = this._getElementIdsWhichInvokeValidation(configuration);
149
+
150
+ for (var i = 0; i < elementIds.length; i++) {
151
+ var element = sys.getById(elementIds[i]);
152
+
153
+ if (sys.isNull(element)) { continue; };
154
+ if (element.edq_eventsAttached === true) { continue; };
155
+
156
+ element.oldValue = element.value;
157
+
158
+ if (element.tagName === "SELECT") {
159
+ var previousOnChange = element.onchange;
160
+
161
+ element.onchange = function (event) {
162
+ if (sys.isFunction(previousOnChange)) {
163
+ previousOnChange.apply(this, [event]);
164
+ };
165
+
166
+ client._validateField(configuration, element, function () { element.oldValue = element.value; });
167
+ };
168
+ } else {
169
+ var previousOnBlur = element.onblur;
170
+
171
+ element.onblur = function (event) {
172
+ if (sys.isFunction(previousOnBlur)) {
173
+ previousOnBlur.apply(this, [event]);
174
+ };
175
+
176
+ if(element.oldValue !== element.value) {
177
+ client._validateField(configuration, element, function () { element.oldValue = element.value; });
178
+ }
179
+ };
180
+ }
181
+
182
+ element.edq_eventsAttached = true;
183
+ };
184
+ };
185
+
186
+ EDQ.DataQuality.Client.prototype._getElementIdsWhichInvokeValidation = function _getElementIdsWhichInvokeValidation(configuration) {
187
+ var sys = EDQ.system;
188
+ var dq = EDQ.DataQuality;
189
+
190
+ var elementIds = [];
191
+
192
+ if (!sys.isNull(configuration._inputMappings) && configuration._inputMappings.length > 0) {
193
+ for (var i = 0; i < configuration._inputMappings.length; i++) {
194
+ for (var j = 0; j < configuration._inputMappings[i].htmlFieldIds.length; j++) {
195
+ elementIds.push(configuration._inputMappings[i].htmlFieldIds[j]);
196
+ }
197
+ }
198
+ } else if (!sys.isNull(configuration._outputMappings) && configuration._outputMappings.length > 0) {
199
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
200
+ elementIds.push(configuration._outputMappings[i].htmlFieldId);
201
+ }
202
+ }
203
+
204
+ return elementIds;
205
+ };
206
+
207
+ EDQ.DataQuality.Client.prototype._validateField = function _validateField(configuration, element, afterValuesSetCallback) {
208
+ var sys = EDQ.system;
209
+ var dq = EDQ.DataQuality;
210
+ var client = dq.Client;
211
+
212
+ var edqFieldName;
213
+ var serviceUrl = '';;
214
+ switch (configuration.type) {
215
+ case 1:
216
+ edqFieldName = dq.Email;
217
+ serviceUrl = this.emailServiceUrl;
218
+ break;
219
+ case 2:
220
+ edqFieldName = dq.Phone;
221
+ serviceUrl = this.phoneServiceUrl;
222
+ break;
223
+ default:
224
+ sys.logError('Unsupported configuration type: ' + configuration.type);
225
+ }
226
+ var sessionToken = this._token;
227
+ var htmlFieldIds = this._getFieldsFromMapping(edqFieldName, configuration);
228
+ var value = '';
229
+ for (var i = 0; i < htmlFieldIds.length; i++) {
230
+ var element = client.getField(htmlFieldIds[i]);
231
+ if (sys.isNull(element)) {
232
+ continue;
233
+ }
234
+
235
+ value += element.value;
236
+ }
237
+ if(sys.isNullOrEmpty(value)) { return; }
238
+
239
+ var countryCode = '';
240
+ var phoneCountryExists = false;
241
+ if (configuration.type === dq.ConfigurationType.Phone) {
242
+ for (var i = 0; i < configuration._inputMappings.length; i++) {
243
+ var inputMapping = configuration._inputMappings[i];
244
+ if(inputMapping.edqFieldName === dq.PhoneCountry) {
245
+ phoneCountryExists = true;
246
+ }
247
+ }
248
+
249
+ if(phoneCountryExists) {
250
+ var countryElements = this._getFieldsFromMapping(dq.PhoneCountry, configuration);
251
+ var country = client.getFieldValue(countryElements[0]);
252
+ countryCode = country;
253
+ } else {
254
+ countryCode = this.defaultCountry;
255
+ }
256
+ }
257
+
258
+ client._setValidationMessageAndLoader(configuration, 'show', '');
259
+
260
+ var postParameters = {};
261
+ if(configuration.type === 1) {
262
+ postParameters = { 'email-address': element.value, 'session-security-token' : sessionToken };
263
+ } else {
264
+ postParameters = { 'telephone-number': element.value, 'telephone-area-code': countryCode, 'session-security-token' : sessionToken };
265
+ }
266
+
267
+ var client = this;
268
+ var request = new Ajax.Request(serviceUrl,
269
+ {
270
+ method: 'post',
271
+ onSuccess: function(transport) {
272
+ client.processResult(transport, configuration, countryCode);
273
+ if(!sys.isNull(afterValuesSetCallback)) {
274
+ afterValuesSetCallback();
275
+ }
276
+ dq.Client._twistLoader(configuration, '');
277
+ },
278
+ onFailure: function(transport) {
279
+ client.processError(transport.xhr, transport.statusText, transport.error, configuration);
280
+ if(!sys.isNull(afterValuesSetCallback)) {
281
+ afterValuesSetCallback();
282
+ }
283
+ },
284
+ parameters: postParameters
285
+ }
286
+ );
287
+ };
288
+
289
+ EDQ.DataQuality.Client.prototype._getFieldsFromMapping = function _getFieldsFromMapping(edqFieldName, configuration) {
290
+ var sys = EDQ.system;
291
+
292
+ var fields = [];
293
+ var fields = configuration.getInputMappingByEdqFieldName(edqFieldName).htmlFieldIds;
294
+
295
+ if (!sys.isNull(fields)) {
296
+ return fields;
297
+ } else {
298
+ fields.push(configuration._getOutputMappingByEdqFieldName(edqFieldName).htmlFieldId);
299
+ }
300
+
301
+ return fields;
302
+ };
303
+
304
+ EDQ.DataQuality.Client.prototype.processResult = function processResult(response, configuration, countryCode) {
305
+ var dq = EDQ.DataQuality;
306
+
307
+ var responseInJson = JSON.parse(response.responseText);
308
+ var certainty = responseInJson.Certainty;
309
+
310
+ switch (configuration.type) {
311
+ case 1:
312
+ responseInJson.ValidationMessageForLabel = (dq.EmailResultCodesAndDescriptions[certainty.toUpperCase()]
313
+ ? dq.EmailResultCodesAndDescriptions[certainty.toUpperCase()]
314
+ : certainty);
315
+ if(responseInJson.Corrections) {
316
+ if(certainty.toUpperCase() !== 'UNKNOWN' && certainty.toUpperCase() !== 'VERIFIED' ) {
317
+ responseInJson.Corrections = '(Suggested: ' + responseInJson.Corrections.join(' ') + ')';
318
+ }
319
+ else {
320
+ responseInJson.Corrections = '';
321
+ }
322
+ }
323
+ break;
324
+ case 2:
325
+ responseInJson.ValidationMessageForLabel = (dq.PhoneResultCodesAndDescriptions[certainty.toUpperCase()]
326
+ ? dq.PhoneResultCodesAndDescriptions[certainty.toUpperCase()]
327
+ : certainty);
328
+ break;
329
+ }
330
+
331
+ responseInJson.ValidationMessage = responseInJson.ValidationMessageForLabel;
332
+
333
+ this.setValues(responseInJson, configuration, countryCode);
334
+ };
335
+
336
+ EDQ.DataQuality.Client.prototype.processError = function processError(xhr, statusText, error, configuration) {
337
+ var dq = EDQ.DataQuality;
338
+ var client = dq.Client;
339
+ var sys = EDQ.system;
340
+
341
+ sys.logError(statusText);
342
+ sys.logError(error);
343
+
344
+ client._setValidationMessageAndLoader(configuration, '', 'Unable to validate.');
345
+ };
346
+
347
+ EDQ.DataQuality.Client._setValidationMessageAndLoader = function _setValidationMessageAndLoader(configuration, loaderDisplayStatus, responseText) {
348
+ var dq = EDQ.DataQuality;
349
+ var client = dq.Client;
350
+ var sys = EDQ.system;
351
+
352
+ var suggestionMessageLabelMapping = configuration._getOutputMappingByEdqFieldName(dq.CorrectionsForLabel);
353
+ var validationMessageMapping = configuration._getOutputMappingByEdqFieldName(dq.ValidationMessageForLabel);
354
+
355
+ if (!sys.isNullOrEmpty(validationMessageMapping)) {
356
+ client._setValidationMessage(validationMessageMapping.htmlFieldId, responseText);
357
+
358
+ if(!sys.isNullOrEmpty(suggestionMessageLabelMapping)) {
359
+ client._setValidationMessage(suggestionMessageLabelMapping.htmlFieldId, '');
360
+ }
361
+
362
+ client._twistLoader(configuration, loaderDisplayStatus);
363
+ }
364
+ };
365
+
366
+ EDQ.DataQuality.Client.prototype.setValues = function setValues(result, configuration, countryCode) {
367
+ var dq = EDQ.DataQuality;
368
+ var sys = EDQ.system;
369
+
370
+ if (sys.isNull(result[dq.ErrorMessage])) {
371
+ for (var i = 0; i < configuration._outputMappings.length; i++) {
372
+ this._setValue(configuration._outputMappings[i], result, configuration.type, countryCode);
373
+ }
374
+ }
375
+ };
376
+
377
+ EDQ.DataQuality.Client.prototype._setValue = function _setValue(mapping, result, type, countryCode) {
378
+ var dq = EDQ.DataQuality;
379
+ var sys = EDQ.system;
380
+ var client = dq.Client;
381
+
382
+ var val = '';
383
+ var edqFieldName = '';
384
+ for (var j = 0; j < mapping.edqFieldNames.length; j++) {
385
+ edqFieldName = mapping.edqFieldNames[j];
386
+ var fieldValue = result[edqFieldName];
387
+
388
+ if (sys.isNullOrEmpty(fieldValue)) {
389
+ continue;
390
+ };
391
+
392
+ if (val.length > 0) {
393
+ val += this.delimiter + ' ';
394
+ };
395
+
396
+ val += fieldValue;
397
+ }
398
+
399
+ if(edqFieldName === dq.ValidationMessageForLabel || edqFieldName === dq.CorrectionsForLabel)
400
+ {
401
+ client._setValidationMessage(mapping.htmlFieldId, result[edqFieldName], result.Certainty, type);
402
+ }
403
+ else
404
+ {
405
+ client.setFieldValue(mapping.htmlFieldId, val);
406
+ }
407
+ };
408
+
409
+ EDQ.DataQuality.Client._setValidationMessage = function _setValidationMessage(textId, text, certainty, type) {
410
+ var sys = EDQ.system;
411
+ var client = EDQ.DataQuality.Client;
412
+
413
+ var validationMessageElement = client.getField(textId);
414
+
415
+ if (!sys.isNull(validationMessageElement)) {
416
+ if(validationMessageElement.tagName === "INPUT") {
417
+ validationMessageElement.value = text;
418
+ } else {
419
+ validationMessageElement.innerHTML = text;
420
+
421
+ validationMessageElement.style.display = sys.isNullOrEmpty(text) ? 'none' : 'inline';
422
+ if(certainty !== undefined && type !== undefined) {
423
+ switch (type) {
424
+ case 1:
425
+ validationMessageElement.style.color = certainty.toUpperCase() === 'VERIFIED' || certainty.toUpperCase() === 'UNKNOWN'
426
+ ? 'rgb(105, 153, 53)'
427
+ : '#D40707';
428
+ break;
429
+ case 2:
430
+ validationMessageElement.style.color = certainty.toUpperCase() === 'UNVERIFIED' || certainty.toUpperCase() === "YOUR REQUEST CANNOT BE COMPLETED. YOUR TOKEN IS EXPIRED"
431
+ ? '#D40707'
432
+ : 'rgb(105, 153, 53)';
433
+ break;
434
+ }
435
+ }
436
+ }
437
+ }
438
+ };
439
+
440
+ EDQ.DataQuality.Client.setFieldValue = function setFieldValue(htmlFieldId, value) {
441
+ var sys = EDQ.system;
442
+ var client = EDQ.DataQuality.Client;
443
+
444
+ var field = client.getField(htmlFieldId);
445
+
446
+ if (sys.isNull(field)) {
447
+ return;
448
+ }
449
+
450
+ field.value = value;
451
+ };
452
+
453
+ EDQ.DataQuality.Client.getFieldValue = function getFieldValue(htmlFieldId) {
454
+ var client = EDQ.DataQuality.Client;
455
+ var sys = EDQ.system;
456
+
457
+ var field = client.getField(htmlFieldId);
458
+ if (sys.isNull(field)) {
459
+ return undefined;
460
+ }
461
+
462
+ return field.value;
463
+ };
464
+
465
+ EDQ.DataQuality.Client.getField = function getField(htmlFieldId) {
466
+ return document.getElementById(htmlFieldId);
467
+ };
468
+
469
+ EDQ.DataQuality.Client._twistLoader = function _twistLoader(configuration, displayStatus) {
470
+ var dq = EDQ.DataQuality;
471
+ var sys = EDQ.system;
472
+ var client = EDQ.DataQuality.Client;
473
+
474
+
475
+ var loaderMapping = configuration._getOutputMappingByEdqFieldName(dq.Loader);
476
+
477
+ if(loaderMapping === undefined) {
478
+ return;
479
+ }
480
+
481
+ var loeaderElement = client.getField(loaderMapping.htmlFieldId);
482
+
483
+ if (!sys.isNull(loeaderElement)) {
484
+ loeaderElement.style.display = displayStatus === 'show' ? 'inline' : 'none' ;
485
+ }
486
+ };
487
+ //Client_End
488
+
489
+ EDQ.DataQuality.ConfigurationType = { Email: 1, Phone: 2 };
490
+
491
+ EDQ.DataQuality.Phone = 'Number';
492
+ EDQ.DataQuality.AreaCode = 'AreaCode';
493
+ EDQ.DataQuality.Email = 'Email';
494
+ EDQ.DataQuality.Message = 'Message';
495
+ EDQ.DataQuality.Certainty = 'Certainty';
496
+ EDQ.DataQuality.ValidationMessageForLabel = 'ValidationMessageForLabel';
497
+ EDQ.DataQuality.ValidationMessage = 'ValidationMessage';
498
+ EDQ.DataQuality.Loader = 'Loader';
499
+ EDQ.DataQuality.ErrorMessage = 'ErrorMessage';
500
+ EDQ.DataQuality.ValidationStatusVerified = 'Verified';
501
+ EDQ.DataQuality.ValidationStatusNotVerified = 'Not verified';
502
+ EDQ.DataQuality.ValidationStatus = 'ValidationStatus';
503
+ EDQ.DataQuality.Country = 'Country';
504
+ EDQ.DataQuality.PhoneCountry = 'PhoneCountry';
505
+ EDQ.DataQuality.Suggested = 'Suggested';
506
+ EDQ.DataQuality.CorrectionsForLabel = 'Corrections';
507
+ EDQ.DataQuality.ResultCode = 'ResultCode';
508
+ EDQ.DataQuality.PhoneType = 'PhoneType';
509
+
510
+ EDQ.DataQuality.PhoneResultCodesAndDescriptions = {
511
+ 'VERIFIED' : 'Verified',
512
+ 'UNVERIFIED' : 'Could not be Verified',
513
+ 'UNKNOWN' : 'Verified',
514
+ 'ABSENT' : 'Verified',
515
+ 'TELESERVICE NOT PROVISIONED' : 'Verified',
516
+ 'CALL BARRED' : 'Verified'
517
+ };
518
+
519
+ EDQ.DataQuality.EmailResultCodesAndDescriptions = {
520
+ 'VERIFIED' : 'Email address validated!',
521
+ 'UNDELIVERABLE' : 'Sorry, username does not exist, or mailbox is suspended or disabled. To proceed, please provide a valid e-mail address.',
522
+ 'UNREACHABLE' : 'Sorry, email domain could not be reached or verified. To proceed, please provide a valid e-mail address.',
523
+ 'ILLEGITIMATE' : 'Email could not be verified. To proceed, please provide a valid e-mail address.',
524
+ 'DISPOSABLE' : 'Sorry, email is suspected as disposable. To proceed, please provide a valid e-mail address.',
525
+ 'UNKNOWN' : 'Email address validated!'
526
+ };
skin/frontend/base/default/edq/js/json2.js ADDED
@@ -0,0 +1,480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ http://www.JSON.org/json2.js
3
+ 2011-02-23
4
+
5
+ Public Domain.
6
+
7
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8
+
9
+ See http://www.JSON.org/js.html
10
+
11
+
12
+ This code should be minified before deployment.
13
+ See http://javascript.crockford.com/jsmin.html
14
+
15
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16
+ NOT CONTROL.
17
+
18
+
19
+ This file creates a global JSON object containing two methods: stringify
20
+ and parse.
21
+
22
+ JSON.stringify(value, replacer, space)
23
+ value any JavaScript value, usually an object or array.
24
+
25
+ replacer an optional parameter that determines how object
26
+ values are stringified for objects. It can be a
27
+ function or an array of strings.
28
+
29
+ space an optional parameter that specifies the indentation
30
+ of nested structures. If it is omitted, the text will
31
+ be packed without extra whitespace. If it is a number,
32
+ it will specify the number of spaces to indent at each
33
+ level. If it is a string (such as '\t' or '&nbsp;'),
34
+ it contains the characters used to indent at each level.
35
+
36
+ This method produces a JSON text from a JavaScript value.
37
+
38
+ When an object value is found, if the object contains a toJSON
39
+ method, its toJSON method will be called and the result will be
40
+ stringified. A toJSON method does not serialize: it returns the
41
+ value represented by the name/value pair that should be serialized,
42
+ or undefined if nothing should be serialized. The toJSON method
43
+ will be passed the key associated with the value, and this will be
44
+ bound to the value
45
+
46
+ For example, this would serialize Dates as ISO strings.
47
+
48
+ Date.prototype.toJSON = function (key) {
49
+ function f(n) {
50
+ // Format integers to have at least two digits.
51
+ return n < 10 ? '0' + n : n;
52
+ }
53
+
54
+ return this.getUTCFullYear() + '-' +
55
+ f(this.getUTCMonth() + 1) + '-' +
56
+ f(this.getUTCDate()) + 'T' +
57
+ f(this.getUTCHours()) + ':' +
58
+ f(this.getUTCMinutes()) + ':' +
59
+ f(this.getUTCSeconds()) + 'Z';
60
+ };
61
+
62
+ You can provide an optional replacer method. It will be passed the
63
+ key and value of each member, with this bound to the containing
64
+ object. The value that is returned from your method will be
65
+ serialized. If your method returns undefined, then the member will
66
+ be excluded from the serialization.
67
+
68
+ If the replacer parameter is an array of strings, then it will be
69
+ used to select the members to be serialized. It filters the results
70
+ such that only members with keys listed in the replacer array are
71
+ stringified.
72
+
73
+ Values that do not have JSON representations, such as undefined or
74
+ functions, will not be serialized. Such values in objects will be
75
+ dropped; in arrays they will be replaced with null. You can use
76
+ a replacer function to replace those with JSON values.
77
+ JSON.stringify(undefined) returns undefined.
78
+
79
+ The optional space parameter produces a stringification of the
80
+ value that is filled with line breaks and indentation to make it
81
+ easier to read.
82
+
83
+ If the space parameter is a non-empty string, then that string will
84
+ be used for indentation. If the space parameter is a number, then
85
+ the indentation will be that many spaces.
86
+
87
+ Example:
88
+
89
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
90
+ // text is '["e",{"pluribus":"unum"}]'
91
+
92
+
93
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95
+
96
+ text = JSON.stringify([new Date()], function (key, value) {
97
+ return this[key] instanceof Date ?
98
+ 'Date(' + this[key] + ')' : value;
99
+ });
100
+ // text is '["Date(---current time---)"]'
101
+
102
+
103
+ JSON.parse(text, reviver)
104
+ This method parses a JSON text to produce an object or array.
105
+ It can throw a SyntaxError exception.
106
+
107
+ The optional reviver parameter is a function that can filter and
108
+ transform the results. It receives each of the keys and values,
109
+ and its return value is used instead of the original value.
110
+ If it returns what it received, then the structure is not modified.
111
+ If it returns undefined then the member is deleted.
112
+
113
+ Example:
114
+
115
+ // Parse the text. Values that look like ISO date strings will
116
+ // be converted to Date objects.
117
+
118
+ myData = JSON.parse(text, function (key, value) {
119
+ var a;
120
+ if (typeof value === 'string') {
121
+ a =
122
+ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123
+ if (a) {
124
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125
+ +a[5], +a[6]));
126
+ }
127
+ }
128
+ return value;
129
+ });
130
+
131
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132
+ var d;
133
+ if (typeof value === 'string' &&
134
+ value.slice(0, 5) === 'Date(' &&
135
+ value.slice(-1) === ')') {
136
+ d = new Date(value.slice(5, -1));
137
+ if (d) {
138
+ return d;
139
+ }
140
+ }
141
+ return value;
142
+ });
143
+
144
+
145
+ This is a reference implementation. You are free to copy, modify, or
146
+ redistribute.
147
+ */
148
+
149
+ /*jslint evil: true, strict: false, regexp: false */
150
+
151
+ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
155
+ test, toJSON, toString, valueOf
156
+ */
157
+
158
+
159
+ // Create a JSON object only if one does not already exist. We create the
160
+ // methods in a closure to avoid creating global variables.
161
+
162
+ var JSON;
163
+ if (!JSON) {
164
+ JSON = {};
165
+ }
166
+
167
+ (function () {
168
+ "use strict";
169
+
170
+ function f(n) {
171
+ // Format integers to have at least two digits.
172
+ return n < 10 ? '0' + n : n;
173
+ }
174
+
175
+ if (typeof Date.prototype.toJSON !== 'function') {
176
+
177
+ Date.prototype.toJSON = function (key) {
178
+
179
+ return isFinite(this.valueOf()) ?
180
+ this.getUTCFullYear() + '-' +
181
+ f(this.getUTCMonth() + 1) + '-' +
182
+ f(this.getUTCDate()) + 'T' +
183
+ f(this.getUTCHours()) + ':' +
184
+ f(this.getUTCMinutes()) + ':' +
185
+ f(this.getUTCSeconds()) + 'Z' : null;
186
+ };
187
+
188
+ String.prototype.toJSON =
189
+ Number.prototype.toJSON =
190
+ Boolean.prototype.toJSON = function (key) {
191
+ return this.valueOf();
192
+ };
193
+ }
194
+
195
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
196
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
197
+ gap,
198
+ indent,
199
+ meta = { // table of character substitutions
200
+ '\b': '\\b',
201
+ '\t': '\\t',
202
+ '\n': '\\n',
203
+ '\f': '\\f',
204
+ '\r': '\\r',
205
+ '"' : '\\"',
206
+ '\\': '\\\\'
207
+ },
208
+ rep;
209
+
210
+
211
+ function quote(string) {
212
+
213
+ // If the string contains no control characters, no quote characters, and no
214
+ // backslash characters, then we can safely slap some quotes around it.
215
+ // Otherwise we must also replace the offending characters with safe escape
216
+ // sequences.
217
+
218
+ escapable.lastIndex = 0;
219
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220
+ var c = meta[a];
221
+ return typeof c === 'string' ? c :
222
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
223
+ }) + '"' : '"' + string + '"';
224
+ }
225
+
226
+
227
+ function str(key, holder) {
228
+
229
+ // Produce a string from holder[key].
230
+
231
+ var i, // The loop counter.
232
+ k, // The member key.
233
+ v, // The member value.
234
+ length,
235
+ mind = gap,
236
+ partial,
237
+ value = holder[key];
238
+
239
+ // If the value has a toJSON method, call it to obtain a replacement value.
240
+
241
+ if (value && typeof value === 'object' &&
242
+ typeof value.toJSON === 'function') {
243
+ value = value.toJSON(key);
244
+ }
245
+
246
+ // If we were called with a replacer function, then call the replacer to
247
+ // obtain a replacement value.
248
+
249
+ if (typeof rep === 'function') {
250
+ value = rep.call(holder, key, value);
251
+ }
252
+
253
+ // What happens next depends on the value's type.
254
+
255
+ switch (typeof value) {
256
+ case 'string':
257
+ return quote(value);
258
+
259
+ case 'number':
260
+
261
+ // JSON numbers must be finite. Encode non-finite numbers as null.
262
+
263
+ return isFinite(value) ? String(value) : 'null';
264
+
265
+ case 'boolean':
266
+ case 'null':
267
+
268
+ // If the value is a boolean or null, convert it to a string. Note:
269
+ // typeof null does not produce 'null'. The case is included here in
270
+ // the remote chance that this gets fixed someday.
271
+
272
+ return String(value);
273
+
274
+ // If the type is 'object', we might be dealing with an object or an array or
275
+ // null.
276
+
277
+ case 'object':
278
+
279
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
280
+ // so watch out for that case.
281
+
282
+ if (!value) {
283
+ return 'null';
284
+ }
285
+
286
+ // Make an array to hold the partial results of stringifying this object value.
287
+
288
+ gap += indent;
289
+ partial = [];
290
+
291
+ // Is the value an array?
292
+
293
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
294
+
295
+ // The value is an array. Stringify every element. Use null as a placeholder
296
+ // for non-JSON values.
297
+
298
+ length = value.length;
299
+ for (i = 0; i < length; i += 1) {
300
+ partial[i] = str(i, value) || 'null';
301
+ }
302
+
303
+ // Join all of the elements together, separated with commas, and wrap them in
304
+ // brackets.
305
+
306
+ v = partial.length === 0 ? '[]' : gap ?
307
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
308
+ '[' + partial.join(',') + ']';
309
+ gap = mind;
310
+ return v;
311
+ }
312
+
313
+ // If the replacer is an array, use it to select the members to be stringified.
314
+
315
+ if (rep && typeof rep === 'object') {
316
+ length = rep.length;
317
+ for (i = 0; i < length; i += 1) {
318
+ if (typeof rep[i] === 'string') {
319
+ k = rep[i];
320
+ v = str(k, value);
321
+ if (v) {
322
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
323
+ }
324
+ }
325
+ }
326
+ } else {
327
+
328
+ // Otherwise, iterate through all of the keys in the object.
329
+
330
+ for (k in value) {
331
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
332
+ v = str(k, value);
333
+ if (v) {
334
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ // Join all of the member texts together, separated with commas,
341
+ // and wrap them in braces.
342
+
343
+ v = partial.length === 0 ? '{}' : gap ?
344
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
345
+ '{' + partial.join(',') + '}';
346
+ gap = mind;
347
+ return v;
348
+ }
349
+ }
350
+
351
+ // If the JSON object does not yet have a stringify method, give it one.
352
+
353
+ if (typeof JSON.stringify !== 'function') {
354
+ JSON.stringify = function (value, replacer, space) {
355
+
356
+ // The stringify method takes a value and an optional replacer, and an optional
357
+ // space parameter, and returns a JSON text. The replacer can be a function
358
+ // that can replace values, or an array of strings that will select the keys.
359
+ // A default replacer method can be provided. Use of the space parameter can
360
+ // produce text that is more easily readable.
361
+
362
+ var i;
363
+ gap = '';
364
+ indent = '';
365
+
366
+ // If the space parameter is a number, make an indent string containing that
367
+ // many spaces.
368
+
369
+ if (typeof space === 'number') {
370
+ for (i = 0; i < space; i += 1) {
371
+ indent += ' ';
372
+ }
373
+
374
+ // If the space parameter is a string, it will be used as the indent string.
375
+
376
+ } else if (typeof space === 'string') {
377
+ indent = space;
378
+ }
379
+
380
+ // If there is a replacer, it must be a function or an array.
381
+ // Otherwise, throw an error.
382
+
383
+ rep = replacer;
384
+ if (replacer && typeof replacer !== 'function' &&
385
+ (typeof replacer !== 'object' ||
386
+ typeof replacer.length !== 'number')) {
387
+ throw new Error('JSON.stringify');
388
+ }
389
+
390
+ // Make a fake root object containing our value under the key of ''.
391
+ // Return the result of stringifying the value.
392
+
393
+ return str('', {'': value});
394
+ };
395
+ }
396
+
397
+
398
+ // If the JSON object does not yet have a parse method, give it one.
399
+
400
+ if (typeof JSON.parse !== 'function') {
401
+ JSON.parse = function (text, reviver) {
402
+
403
+ // The parse method takes a text and an optional reviver function, and returns
404
+ // a JavaScript value if the text is a valid JSON text.
405
+
406
+ var j;
407
+
408
+ function walk(holder, key) {
409
+
410
+ // The walk method is used to recursively walk the resulting structure so
411
+ // that modifications can be made.
412
+
413
+ var k, v, value = holder[key];
414
+ if (value && typeof value === 'object') {
415
+ for (k in value) {
416
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
417
+ v = walk(value, k);
418
+ if (v !== undefined) {
419
+ value[k] = v;
420
+ } else {
421
+ delete value[k];
422
+ }
423
+ }
424
+ }
425
+ }
426
+ return reviver.call(holder, key, value);
427
+ }
428
+
429
+
430
+ // Parsing happens in four stages. In the first stage, we replace certain
431
+ // Unicode characters with escape sequences. JavaScript handles many characters
432
+ // incorrectly, either silently deleting them, or treating them as line endings.
433
+
434
+ text = String(text);
435
+ cx.lastIndex = 0;
436
+ if (cx.test(text)) {
437
+ text = text.replace(cx, function (a) {
438
+ return '\\u' +
439
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
440
+ });
441
+ }
442
+
443
+ // In the second stage, we run the text against regular expressions that look
444
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
445
+ // because they can cause invocation, and '=' because it can cause mutation.
446
+ // But just to be safe, we want to reject all unexpected forms.
447
+
448
+ // We split the second stage into 4 regexp operations in order to work around
449
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
450
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
451
+ // replace all simple value tokens with ']' characters. Third, we delete all
452
+ // open brackets that follow a colon or comma or that begin the text. Finally,
453
+ // we look to see that the remaining characters are only whitespace or ']' or
454
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
455
+
456
+ if (/^[\],:{}\s]*$/
457
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
458
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
459
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
460
+
461
+ // In the third stage we use the eval function to compile the text into a
462
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
463
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
464
+ // in parens to eliminate the ambiguity.
465
+
466
+ j = eval('(' + text + ')');
467
+
468
+ // In the optional fourth stage, we recursively walk the new structure, passing
469
+ // each name/value pair to a reviver function for possible transformation.
470
+
471
+ return typeof reviver === 'function' ?
472
+ walk({'': j}, '') : j;
473
+ }
474
+
475
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
476
+
477
+ throw new SyntaxError('JSON.parse');
478
+ };
479
+ }
480
+ }());
skin/frontend/base/default/edq/js/system.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var EDQ = EDQ || {};
2
+ EDQ.system = EDQ.system || {};
3
+
4
+ EDQ.system.isUndefined = function isUndefined(value) { return typeof(value) == "undefined"; };
5
+ EDQ.system.isNull = function isNull(value) { return EDQ.system.isUndefined(value) || value == null; };
6
+ EDQ.system.isNullOrEmpty = function isNullOrEmpty(str) { return EDQ.system.isNull(str) || str == ""; };
7
+ EDQ.system.isFunction = function isFunction(obj) { return !EDQ.system.isNull(obj) && Object.prototype.toString.call(obj) === '[object Function]'; };
8
+ EDQ.system.logError = function logError(obj) {
9
+ if (window.console) {
10
+ window.console.log(obj);
11
+ } else { //IE does not have a logger.
12
+ //alert(obj);
13
+ };
14
+ };
15
+
16
+ EDQ.system.inherit = (function () {
17
+ var F = function (){};
18
+ return function (C, P) {
19
+ F.prototype = P.prototype;
20
+ C.prototype = new F();
21
+ C.uber = P.prototype;
22
+ C.prototype.constructor = C;
23
+ }
24
+ }());
25
+
26
+ if (Array && !Array.indexOf){
27
+ Array.prototype.indexOf = function (elt /*, from*/) {
28
+ var len = this.length;
29
+
30
+ var from = Number(arguments[1]) || 0;
31
+ from = (from < 0)? Math.ceil(from) : Math.floor(from);
32
+ if (from < 0) { from += len; }
33
+ for (; from < len; from++) {
34
+ if (from in this && this[from] === elt) { return from;}
35
+ }
36
+ return -1;
37
+ };
38
+ };
39
+
40
+ EDQ.system.getById = function getById(selector) {
41
+ return document.getElementById(selector);
42
+ };
43
+
44
+ EDQ.system.beginsWith = function beginsWith(needle, haystack) {
45
+ return (haystack.substr(0, needle.length) == needle);
46
+ };