AeliaWCEU_VAT_AssistantWC_Aelia_EU_VAT_Assistant_Install

Runs automatic updates for the EU VAT Assistant plugin.

Defined (1)

The class is defined in the following location(s).

/src/lib/classes/install/aelia-wc-eu-vat-assistant-install.php  
  1. class WC_Aelia_EU_VAT_Assistant_Install extends \Aelia\WC\Aelia_Install { 
  2. // @var string The name of the lock that will be used by the installer to prevent race conditions. 
  3. protected $lock_name = 'WC_AELIA_EU_VAT_ASSISTANT'; 
  4. // @var string The text domain, used for localisation. 
  5. protected $text_domain; 
  6.  
  7. /** 
  8. * Returns the instance of the EU VAT Assistant plugin. 
  9. * @return \Aelia\WC\EU_VAT_Assistant\WC_Aelia_EU_VAT_Assistant 
  10. * @since 1.3.20.150330 
  11. */ 
  12. protected function EUVA() { 
  13. return WC_Aelia_EU_VAT_Assistant::instance(); 
  14.  
  15. /** 
  16. * Class constructor. 
  17. */ 
  18. public function __construct() { 
  19. parent::__construct(); 
  20. $this->logger = new Logger(Definitions::PLUGIN_SLUG); 
  21. $this->text_domain = DEFINITIONS::TEXT_DOMAIN; 
  22.  
  23. /** 
  24. * Updates the VAT data for the orders saved by the EU VAT Assistant 0.9.8.x. 
  25. * and earlier. 
  26. * @return bool 
  27. * @since 0.9.9.141223 
  28. */ 
  29. protected function update_to_0_9_9_141223() { 
  30. // Retrieve the exchange rates for the orders whose data already got 
  31. // partially converted 
  32. $SQL = " 
  33. SELECT 
  34. PM.post_id AS order_id 
  35. , PM.meta_value AS eu_vat_data 
  36. FROM 
  37. {$this->wpdb->postmeta} AS PM 
  38. WHERE 
  39. (PM.meta_key = '_eu_vat_data') 
  40. "; 
  41.  
  42. $orders_to_update = $this->select($SQL); 
  43. // Debug 
  44. //var_dump($orders_to_update); die(); 
  45.  
  46. foreach($orders_to_update as $order_meta) { 
  47. $eu_vat_data = maybe_unserialize($order_meta->eu_vat_data); 
  48. // Skip VAT data that is already in the correct format 
  49. $vat_data_version = get_value('eu_vat_assistant_version', $eu_vat_data); 
  50. if(version_compare($vat_data_version, '0.9.9.141223', '>=')) { 
  51. continue; 
  52.  
  53. // Add tax rate details to the all orders having VAT data that doesn't 
  54. // already contain such information 
  55. $order = new Order($order_meta->order_id); 
  56. $order->update_vat_data(); 
  57. return true; 
  58.  
  59. /** 
  60. * Updates the VAT data for the orders saved by the EU VAT Assistant 0.10.0.x 
  61. * and earlier. 
  62. * @return bool 
  63. * @since 0.10.1.141230 
  64. */ 
  65. protected function update_to_0_10_1_141230() { 
  66. // Retrieve the exchange rates for the orders whose data already got 
  67. // partially converted 
  68. $SQL = " 
  69. SELECT 
  70. PM.post_id AS order_id 
  71. , PM.meta_value AS eu_vat_data 
  72. FROM 
  73. {$this->wpdb->postmeta} AS PM 
  74. WHERE 
  75. (PM.meta_key = '_eu_vat_data') 
  76. "; 
  77.  
  78. $orders_to_update = $this->select($SQL); 
  79. // Debug 
  80. //var_dump($orders_to_update); die(); 
  81.  
  82. foreach($orders_to_update as $order_meta) { 
  83. $eu_vat_data = maybe_unserialize($order_meta->eu_vat_data); 
  84. // Skip VAT data that is already in the correct format 
  85. $vat_data_version = get_value('eu_vat_assistant_version', $eu_vat_data); 
  86. if(version_compare($vat_data_version, '0.10.1.141230', '>=')) { 
  87. continue; 
  88.  
  89. // Add tax rate details to the all orders having VAT data that doesn't 
  90. // already contain such information 
  91. $order = new Order($order_meta->order_id); 
  92. $order->update_vat_data(); 
  93. return true; 
  94.  
  95. /** 
  96. * Runs the updates required by the EU VAT Assistant 1.1.3.150111 and later. 
  97. * @return bool 
  98. * @since 1.1.3.150111 
  99. */ 
  100. protected function update_to_1_1_3_150111() { 
  101. global $wpdb; 
  102.  
  103. // Adds an extra column to the taxes table, to keep track of whic country 
  104. // each tax should be paid to 
  105. $table_name = $wpdb->prefix . 'woocommerce_tax_rates'; 
  106. $column_name = 'tax_payable_to_country'; 
  107. if($this->column_exists($table_name, $column_name)) { 
  108. return true; 
  109. /** Note: we are using the extremely large VARCHAR(200) type for the 
  110. * "tax_payable_to_country" column because the core "tax_rate_country" 
  111. * column is also using the same. Since both columns are going to contain a 
  112. * country, it makes sense that they have the same type (although the size 
  113. * is probably excessive). 
  114. */ 
  115. return $this->add_column($table_name, $column_name, 'VARCHAR(200)'); 
  116.  
  117. /** 
  118. * Runs the updates required by the EU VAT Assistant 1.2.0.150215 and later. 
  119. * @return bool 
  120. * @since 1.2.0.150215 
  121. */ 
  122. protected function update_to_1_2_0_150215() { 
  123. $this->start_transaction(); 
  124.  
  125. try { 
  126. $table_name = $this->wpdb->prefix . 'aelia_exchange_rates_history'; 
  127. $SQL = " 
  128. CREATE TABLE IF NOT EXISTS `$table_name` ( 
  129. `provider_name` varchar(200) COLLATE utf8_unicode_ci NOT NULL,  
  130. `base_currency` char(3) NOT NULL,  
  131. `rates_date` datetime NOT NULL,  
  132. `rates` longtext COLLATE utf8_unicode_ci DEFAULT NULL,  
  133. `date_updated` datetime DEFAULT NULL,  
  134. PRIMARY KEY (`provider_name`, `rates_date`) 
  135. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
  136. "; 
  137. $result = $this->exec($SQL); 
  138.  
  139. if($result === false) { 
  140. $this->add_message(E_USER_ERROR,  
  141. sprintf(__('Creation of table "%s" failed. Please ' . 
  142. 'check PHP error log for error messages ' . 
  143. 'related to the operation.', $this->text_domain),  
  144. $table_name)); 
  145. $this->rollback_transaction(); 
  146. else { 
  147. $this->add_message(E_USER_NOTICE,  
  148. sprintf(__('Table "%s" created successfullly.', $this->text_domain),  
  149. $table_name)); 
  150. $this->commit_transaction(); 
  151. $result = true; 
  152. catch(Exception $e) { 
  153. $this->rollback_transaction(); 
  154. $this->log($e->getMessage()); 
  155. $this->add_message(E_USER_ERROR, $e->getMessage()); 
  156. return false; 
  157. return (bool)$result; 
  158.  
  159. /** 
  160. * Runs the following updates required by the EU VAT Assistant 1.2.1.150215 
  161. * and later: 
  162. * - Ensures the the EU VAT data saved with all orders contains the tax class 
  163. * of each tax rate. 
  164. * @return bool 
  165. * @since 1.2.1.150215 
  166. */ 
  167. protected function update_to_1_2_1_150215() { 
  168. $this->start_transaction(); 
  169. try { 
  170. $SQL = " 
  171. SELECT 
  172. TR.tax_rate_id 
  173. , TR.tax_rate_class 
  174. FROM 
  175. {$this->wpdb->prefix}woocommerce_tax_rates TR 
  176. "; 
  177.  
  178. $tax_rates_data = $this->select($SQL, OBJECT_K); 
  179. // Debug 
  180. //var_dump($tax_rates_data); die(); 
  181.  
  182. // Retrieve past orders 
  183. $SQL = " 
  184. SELECT 
  185. PM.post_id AS order_id 
  186. , PM.meta_value AS eu_vat_data 
  187. FROM 
  188. {$this->wpdb->postmeta} AS PM 
  189. WHERE 
  190. (PM.meta_key = '_eu_vat_data') 
  191. "; 
  192.  
  193. $orders_to_update = $this->select($SQL); 
  194. // Debug 
  195. //var_dump($orders_to_update); die(); 
  196.  
  197. foreach($orders_to_update as $order_meta) { 
  198. $eu_vat_data = maybe_unserialize($order_meta->eu_vat_data); 
  199. // Skip VAT data that is already in the correct format 
  200. $vat_data_version = get_value('eu_vat_assistant_version', $eu_vat_data); 
  201. if(version_compare($vat_data_version, '1.2.1.150215', '>=')) { 
  202. continue; 
  203.  
  204. if(empty($eu_vat_data['taxes']) || !is_array($eu_vat_data['taxes'])) { 
  205. continue; 
  206.  
  207. foreach($eu_vat_data['taxes'] as $rate_id => $tax_info) { 
  208. if(isset($tax_info['tax_rate_class'])) { 
  209. continue; 
  210.  
  211. $tax_rate = get_value($rate_id, $tax_rates_data); 
  212. if(!empty($tax_rate)) { 
  213. // Note: an empty tax rate class is not an error. It simply represents the 
  214. // "Standard" class 
  215. $tax_info['tax_rate_class'] = $tax_rate->tax_rate_class; 
  216. $eu_vat_data['taxes'][$rate_id] = $tax_info; 
  217. $eu_vat_data['eu_vat_assistant_version'] = '1.2.1.150215'; 
  218.  
  219. // Debug 
  220. //var_dump($eu_vat_data);die(); 
  221. update_post_meta($order_meta->order_id, '_eu_vat_data', $eu_vat_data); 
  222. $this->commit_transaction(); 
  223. $result = true; 
  224. catch(Exception $e) { 
  225. $this->rollback_transaction(); 
  226. $this->log($e->getMessage()); 
  227. $this->add_message(E_USER_ERROR, $e->getMessage()); 
  228. $result = false; 
  229. return $result; 
  230.  
  231. /** 
  232. * Updates the VAT numbers stored with the orders, to ensure that they contain 
  233. * the correct prefix. 
  234. * @return bool 
  235. * @since 1.3.20.150330 
  236. */ 
  237. protected function update_to_1_3_20_150330() { 
  238. $px = $this->wpdb->prefix; 
  239.  
  240. // Retrieve the orders that have a valid EU VAT number 
  241. $SQL = " 
  242. SELECT 
  243. ORDER_META.post_id AS order_id 
  244. , ORDER_META.meta_value AS eu_vat_evidence 
  245. FROM 
  246. {$this->wpdb->postmeta} AS ORDER_META 
  247. INNER JOIN 
  248. {$px}postmeta AS ORDER_META2 ON 
  249. (ORDER_META2.post_id = ORDER_META.post_id) AND 
  250. (ORDER_META2.meta_key = '_vat_number_validated') AND 
  251. (ORDER_META2.meta_value = 'valid') 
  252. WHERE 
  253. (ORDER_META.meta_key = '_eu_vat_evidence') 
  254. "; 
  255.  
  256. $orders_to_update = $this->select($SQL); 
  257. // Debug 
  258. //var_dump($orders_to_update); die(); 
  259.  
  260. foreach($orders_to_update as $order_meta) { 
  261. $eu_vat_evidence = maybe_unserialize($order_meta->eu_vat_evidence); 
  262. // Skip VAT evidence that is already in the correct format 
  263. $vat_evidence_version = get_value('eu_vat_assistant_version', $eu_vat_evidence); 
  264. if(version_compare($vat_evidence_version, '1.3.20.150330', '>=')) { 
  265. continue; 
  266.  
  267. /** Only process orders that actually have a VAT number associated. The SQL 
  268. * should have filtered the ones that don't have such data, but this extra 
  269. * check will filter out orders that have been tampered with. 
  270. */ 
  271. $vat_number = trim(get_value('vat_number', $eu_vat_evidence['exemption'])); 
  272. $vat_country = trim(get_value('vat_country', $eu_vat_evidence['exemption'])); 
  273. if(empty($vat_number) || empty($vat_country)) { 
  274. continue; 
  275.  
  276. // Replace the VAT number with the full one, inclusive of country prefix 
  277. $order_vat_number = (string)$this->EUVA()->get_full_vat_number($vat_country, $vat_number); 
  278. if(empty($order_vat_number)) { 
  279. $this->log(sprintf(__('Order ID "%s". Invalid VAT Number parsed: "%s".', $this->text_domain),  
  280. $order_id,  
  281. $order_vat_number), false); 
  282. $eu_vat_evidence['exemption']['vat_number'] = $order_vat_number; 
  283. update_post_meta($order_meta->order_id, '_eu_vat_evidence', $eu_vat_evidence); 
  284. update_post_meta($order_meta->order_id, 'vat_number', $order_vat_number); 
  285. return true; 
  286.  
  287. /** 
  288. * Overrides standard update method to ensure that requirements for update are 
  289. * in place. 
  290. * @param string plugin_id The ID of the plugin. 
  291. * @param string new_version The new version of the plugin, which will be 
  292. * stored after a successful update to keep track of the status. 
  293. * @return bool 
  294. */ 
  295. public function update($plugin_id, $new_version) { 
  296. //delete_option($plugin_id); 
  297. return parent::update($plugin_id, $new_version);