AeliaWCEU_VAT_AssistantSettings_Renderer

Implements a class that will render the settings page.

Defined (1)

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

/src/lib/classes/settings/settings-renderer.php  
  1. class Settings_Renderer extends \Aelia\WC\Settings_Renderer { 
  2. // @var string The URL to the support portal. 
  3. const SUPPORT_URL = 'http://aelia.freshdesk.com/support/home'; 
  4. // @var string The URL to the contact form for general enquiries. 
  5. const CONTACT_URL = 'http://aelia.co/contact/'; 
  6.  
  7. /*** Settings Tabs ***/ 
  8. const TAB_CHECKOUT = 'checkout'; 
  9. const TAB_SELF_CERTIFICATION = 'self-certification'; 
  10. const TAB_CURRENCY = 'currency'; 
  11. const TAB_SALES = 'sales'; 
  12. const TAB_REPORTS = 'reports'; 
  13. const TAB_OPTIONS = 'options'; 
  14. const TAB_LINKS = 'links'; 
  15. const TAB_SUPPORT = 'support'; 
  16.  
  17. /*** Settings sections ***/ 
  18. const SECTION_CHECKOUT = 'checkout'; 
  19. const SECTION_SELF_CERTIFICATION = 'self_certification'; 
  20. const SECTION_CURRENCY = 'currency'; 
  21. const SECTION_EXCHANGE_RATES_UPDATE = 'exchange_rates_update'; 
  22. const SECTION_EXCHANGE_RATES = 'exchange_rates'; 
  23. const SECTION_REPORTS = 'reports'; 
  24. const SECTION_SALE_RESTRICTIONS = 'sale_restrictions'; 
  25. const SECTION_OPTIONS = 'options'; 
  26. const SECTION_LINKS = 'links'; 
  27. const SECTION_DEBUG = 'debug'; 
  28. const SECTION_SUPPORT = 'support_section'; 
  29.  
  30. /** 
  31. * Transforms an array of currency codes into an associative array of 
  32. * currency code => currency description entries. Currency labels are retrieved 
  33. * from the list of currencies available in WooCommerce. 
  34. * @param array currencies An array of currency codes. 
  35. * @return array 
  36. */ 
  37. protected function add_currency_labels(array $currencies) { 
  38. $woocommerce_currencies = get_woocommerce_currencies(); 
  39.  
  40. // Add the VAT currency to the list, in case it's not already there 
  41. $currencies[] = $this->_settings_controller->vat_currency(); 
  42.  
  43. $result = array(); 
  44. foreach($currencies as $currency_code) { 
  45. $result[$currency_code] = get_value($currency_code,  
  46. $woocommerce_currencies,  
  47. sprintf(__('Label not found for currency "%s"', $this->_textdomain),  
  48. $currency_code)); 
  49.  
  50. return $result; 
  51.  
  52. /** 
  53. * Sets the tabs to be used to render the Settings page. 
  54. */ 
  55. protected function add_settings_tabs() { 
  56. // Checkout settings 
  57. $this->add_settings_tab($this->_settings_key,  
  58. self::TAB_CHECKOUT,  
  59. __('Checkout', $this->_textdomain)); 
  60. // Self-certification 
  61. $this->add_settings_tab($this->_settings_key,  
  62. self::TAB_SELF_CERTIFICATION,  
  63. __('Self-certification', $this->_textdomain)); 
  64. // Currency 
  65. $this->add_settings_tab($this->_settings_key,  
  66. self::TAB_CURRENCY,  
  67. __('Currency', $this->_textdomain)); 
  68. // Sales 
  69. $this->add_settings_tab($this->_settings_key,  
  70. self::TAB_SALES,  
  71. __('Sales', $this->_textdomain)); 
  72. // Reports 
  73. $this->add_settings_tab($this->_settings_key,  
  74. self::TAB_REPORTS,  
  75. __('Reports', $this->_textdomain)); 
  76. // Options 
  77. $this->add_settings_tab($this->_settings_key,  
  78. self::TAB_OPTIONS,  
  79. __('Options', $this->_textdomain)); 
  80. // Shortcuts 
  81. //$this->add_settings_tab($this->_settings_key,  
  82. // self::TAB_LINKS,  
  83. // __('Shortcuts', $this->_textdomain)); 
  84. // Support tab 
  85. $this->add_settings_tab($this->_settings_key,  
  86. self::TAB_SUPPORT,  
  87. __('Support', $this->_textdomain)); 
  88.  
  89. /** 
  90. * Configures the plugin settings sections. 
  91. */ 
  92. protected function add_settings_sections() { 
  93. // Add checkout settings section 
  94. $this->add_settings_section( 
  95. self::SECTION_CHECKOUT,  
  96. __('Checkout settings', $this->_textdomain),  
  97. array($this, 'checkout_section_callback'),  
  98. $this->_settings_key,  
  99. self::TAB_CHECKOUT 
  100. ); 
  101. // Add self-certification settings section 
  102. $this->add_settings_section( 
  103. self::SECTION_SELF_CERTIFICATION,  
  104. __('Self-certification settings', $this->_textdomain),  
  105. array($this, 'self_certification_section_callback'),  
  106. $this->_settings_key,  
  107. self::TAB_SELF_CERTIFICATION 
  108. ); 
  109. // Add currency section 
  110. $this->add_settings_section( 
  111. self::SECTION_CURRENCY,  
  112. __('Currency', $this->_textdomain),  
  113. array($this, 'currency_section_callback'),  
  114. $this->_settings_key,  
  115. self::TAB_CURRENCY 
  116. ); 
  117. $this->add_settings_section( 
  118. self::SECTION_EXCHANGE_RATES_UPDATE,  
  119. __('Automatic update of exchange rates', $this->_textdomain),  
  120. array($this, 'exchange_rates_update_section_callback'),  
  121. $this->_settings_key,  
  122. self::TAB_CURRENCY 
  123. ); 
  124. $this->add_settings_section( 
  125. self::SECTION_EXCHANGE_RATES,  
  126. __('Exchange rates', $this->_textdomain),  
  127. array($this, 'exchange_rates_section_callback'),  
  128. $this->_settings_key,  
  129. self::TAB_CURRENCY 
  130. ); 
  131. // Add sales section 
  132. $this->add_settings_section( 
  133. self::SECTION_SALE_RESTRICTIONS,  
  134. __('Sale restrictions', $this->_textdomain),  
  135. array($this, 'sale_restrictions_section_callback'),  
  136. $this->_settings_key,  
  137. self::TAB_SALES 
  138. ); 
  139. // Add reports section 
  140. $this->add_settings_section( 
  141. self::SECTION_REPORTS,  
  142. __('Reports settings', $this->_textdomain),  
  143. array($this, 'reports_section_callback'),  
  144. $this->_settings_key,  
  145. self::TAB_REPORTS 
  146. ); 
  147. // Add options section 
  148. $this->add_settings_section( 
  149. self::SECTION_OPTIONS,  
  150. __('Options', $this->_textdomain),  
  151. array($this, 'options_section_callback'),  
  152. $this->_settings_key,  
  153. self::TAB_OPTIONS 
  154. ); 
  155. // Add Links section 
  156. $this->add_settings_section( 
  157. self::SECTION_LINKS,  
  158. __('Shortcuts', $this->_textdomain),  
  159. array($this, 'links_section_callback'),  
  160. $this->_settings_key,  
  161. self::TAB_REPORTS 
  162. ); 
  163. // Add Support section 
  164. $this->add_settings_section( 
  165. self::SECTION_SUPPORT,  
  166. __('Support Information', $this->_textdomain),  
  167. array($this, 'support_section_callback'),  
  168. $this->_settings_key,  
  169. self::TAB_SUPPORT 
  170. ); 
  171. // Add Debug section 
  172. $this->add_settings_section( 
  173. self::SECTION_DEBUG,  
  174. __('Debug', $this->_textdomain),  
  175. array($this, 'debug_section_callback'),  
  176. $this->_settings_key,  
  177. self::TAB_SUPPORT 
  178. ); 
  179.  
  180. /** 
  181. * Configures the plugin settings fields. 
  182. */ 
  183. protected function add_settings_fields() { 
  184. // Checkout settings 
  185. $eu_vat_number_field_handling_options = array( 
  186. Settings::OPTION_EU_VAT_NUMBER_FIELD_OPTIONAL => __('Optional', $this->_textdomain),  
  187. Settings::OPTION_EU_VAT_NUMBER_FIELD_REQUIRED => __('Always required',  
  188. $this->_textdomain),  
  189. Settings::OPTION_EU_VAT_NUMBER_FIELD_REQUIRED_EU_ONLY => __('Required only for EU addresses',  
  190. $this->_textdomain),  
  191. Settings::OPTION_EU_VAT_NUMBER_FIELD_REQUIRED_IF_COMPANY_FILLED => __('Required if customer enters a company name',  
  192. $this->_textdomain),  
  193. Settings::OPTION_EU_VAT_NUMBER_FIELD_REQUIRED_IF_COMPANY_FILLED_EU_ONLY => __('Required if customer enters a company name (EU addresses only)',  
  194. $this->_textdomain),  
  195. Settings::OPTION_EU_VAT_NUMBER_FIELD_HIDDEN => __('Hidden',  
  196. $this->_textdomain),  
  197. ); 
  198. $this->render_dropdown_field(self::SECTION_CHECKOUT,  
  199. Settings::FIELD_EU_VAT_NUMBER_FIELD_REQUIRED,  
  200. __('EU VAT number field will be', $this->_textdomain),  
  201. $eu_vat_number_field_handling_options,  
  202. __('Choose if you would like to display the EU VAT Number field, and ' . 
  203. 'how you would like to handle it.'. 
  204. '<ul class="description">' . 
  205. '<li><strong>Optional</strong> - Customers can enter a EU VAT ' . 
  206. 'number to get VAT exemption.</li>' . 
  207. '<li><strong>Always required</strong> - Customers must enter a ' . 
  208. 'valid EU VAT number to complete a purchase. This means that ' . 
  209. 'only B2B sales with EU businesses can be completed.</li>' . 
  210. '<li><strong>Required only for EU addresses</strong> - Customers ' . 
  211. 'who select a billing country that is part of the EU must enter a ' . 
  212. 'valid EU VAT number to complete a purchase. Customer who select ' . 
  213. 'a non-EU country can proceed without entering the VAT number.</li>' . 
  214. '<li><strong>Hidden</strong> - Customers will not be able ' . 
  215. 'to enter a EU VAT number. This option is useful if you do not ' . 
  216. 'plan to sell to EU businesses.</li>' . 
  217. '</ul>',  
  218. $this->_textdomain),  
  219. ''); 
  220. // Label for EU VAT field 
  221. $this->render_text_field(self::SECTION_CHECKOUT,  
  222. Settings::FIELD_EU_VAT_FIELD_TITLE,  
  223. __('EU VAT field label', $this->_textdomain),  
  224. __('The label that will be displayed above the EU VAT field at checkout.',  
  225. $this->_textdomain),  
  226. 'title'); 
  227. // Description for EU VAT field 
  228. $this->render_text_field(self::SECTION_CHECKOUT,  
  229. Settings::FIELD_EU_VAT_FIELD_DESCRIPTION,  
  230. __('EU VAT field description', $this->_textdomain),  
  231. __('A description that will be displayed above the EU VAT field at checkout.',  
  232. $this->_textdomain),  
  233. 'description'); 
  234. $this->render_checkbox_field(self::SECTION_CHECKOUT,  
  235. Settings::FIELD_SHOW_EU_VAT_FIELD_IF_CUSTOMER_IN_BASE_COUNTRY,  
  236. __('Show EU VAT field when customer is located in base country', $this->_textdomain),  
  237. __('Show the EU VAT field when customer address is located in any European ' . 
  238. 'country, including your shop\'s base country. If this option is <strong>not</strong> selected, ' . 
  239. 'the EU VAT field will be hidden when the customer is from the same country specified ' . 
  240. 'as your shop\'s base country.',  
  241. $this->_textdomain),  
  242. ''); 
  243. $this->render_checkbox_field(self::SECTION_CHECKOUT,  
  244. Settings::FIELD_REMOVE_VAT_IF_CUSTOMER_IN_BASE_COUNTRY,  
  245. __('Deduct VAT if customer is located in base country', $this->_textdomain),  
  246. __('Enable this option to deduct VAT from orders placed by customers who are located ' . 
  247. 'in your shop\'s base country, if they enter a valid EU VAT number.',  
  248. $this->_textdomain),  
  249. ''); 
  250. $this->render_checkbox_field(self::SECTION_CHECKOUT,  
  251. Settings::FIELD_STORE_INVALID_VAT_NUMBERS,  
  252. __('Store invalid VAT numbers', $this->_textdomain),  
  253. __('Enable this option to store VAT numbers that don\'t pass ' . 
  254. 'validation. Note: when an invalid VAT number is detected, ' . 
  255. 'VAT will still be applied.',  
  256. $this->_textdomain),  
  257. ''); 
  258. $this->render_checkbox_field(self::SECTION_CHECKOUT,  
  259. Settings::FIELD_ACCEPT_VAT_NUMBER_WHEN_VALIDATION_SERVER_BUSY,  
  260. __('Accept VAT numbers that cannot be validated due to server busy', $this->_textdomain),  
  261. __('VAT numbers are validates using EU VIES service. Occasionally, ' . 
  262. 'the VIES server may return a "busy" response, which means that ' . 
  263. 'the VAT number was not processed and its validity is unknown. ' . 
  264. 'If you enable this option, a VAT number that cannot be validated ' . 
  265. 'due to the VIES server being busy will be accepted, and the ' . 
  266. 'customer will be considered exempt from VAT.',  
  267. $this->_textdomain),  
  268. ''); 
  269. // Self-certification 
  270. $self_certification_show_options = array( 
  271. Settings::OPTION_SELF_CERTIFICATION_FIELD_NO => __('No (never show it)', $this->_textdomain),  
  272. Settings::OPTION_SELF_CERTIFICATION_FIELD_YES => __('Yes (always show it)', $this->_textdomain),  
  273. Settings::OPTION_SELF_CERTIFICATION_FIELD_CONFLICT_ONLY => __('Only when there is insufficient ' . 
  274. 'evidence about customer\'s location', $this->_textdomain),  
  275. ); 
  276. $this->render_dropdown_field(self::SECTION_SELF_CERTIFICATION,  
  277. Settings::FIELD_SHOW_SELF_CERTIFICATION_FIELD,  
  278. __('Allow customers to self-certify their location of residence', $this->_textdomain),  
  279. $self_certification_show_options,  
  280. __('Choose if you would like to display a "self-certification" field at ' . 
  281. 'checkout. By ticking the self-certification box, customers will be ' . 
  282. 'allowed to certify that the country entered as part of the billing ' . 
  283. 'address is their country of residence. Such declaration will be ' . 
  284. 'recorded with the completed order as part of the EU VAT evidence.',  
  285. $this->_textdomain),  
  286. ''); 
  287. $this->render_checkbox_field(self::SECTION_SELF_CERTIFICATION,  
  288. Settings::FIELD_SELF_CERTIFICATION_FIELD_REQUIRED_WHEN_CONFLICT,  
  289. __('Require self-certification when the evidence about location is insufficient', $this->_textdomain),  
  290. __('<a href="http://en.wikipedia.org/wiki/European_Union_value_added_tax#EU_VAT_area">' . 
  291. 'EU regulations require at least two pieces of non-conflicting ' . 
  292. 'evidence</a> to prove a customer\'s location (e.g. billing address, shipping ' . 
  293. 'address, IP address). If you enable this option, the self-certification ' . 
  294. 'will become mandatory unless at least two of these information will ' . 
  295. 'match the same country. <strong>Important</strong>: this rule ' . 
  296. 'applies only when the self-certification field is visible to the ' . 
  297. 'customer (see visibility options, above).',  
  298. $this->_textdomain),  
  299. ''); 
  300. $this->render_checkbox_field(self::SECTION_SELF_CERTIFICATION,  
  301. Settings::FIELD_USE_SHIPPING_ADDRESS_AS_EVIDENCE,  
  302. __('Consider the shipping address as valid location evidence', $this->_textdomain),  
  303. __('Tick this box if you would like to use the shipping address ' . 
  304. 'as evidence to validate customer\'s location. When this ' . 
  305. 'option is enabled, and the customer enters the same country ' . 
  306. 'in both billing and shipping address, the plugin will consider ' . 
  307. 'them two pieces of non contradictory evidence and it will no ' . 
  308. 'longer ask for self-certification. ' . 
  309. 'We would recommend that you discuss with your Revenue office ' . 
  310. 'the possibility of using the shipping address as evidence ' . 
  311. 'before enabling this option.',  
  312. $this->_textdomain),  
  313. ''); 
  314. $this->render_checkbox_field(self::SECTION_SELF_CERTIFICATION,  
  315. Settings::FIELD_HIDE_SELF_CERTIFICATION_FIELD_VALID_VAT_NUMBER,  
  316. __('Hide the self-certification field when a valid VAT number is entered', $this->_textdomain),  
  317. __('Enable this option if you would like to hide the self-certification ' . 
  318. 'field at checkout even when the customer enters a valid VAT number. ' . 
  319. '<strong>Important</strong>: when this option is enabled, if the ' . 
  320. 'customer will enter a valid VAT number the self-certification ' . 
  321. 'requirement above will be ignored.',  
  322. $this->_textdomain),  
  323. ''); 
  324. $this->render_text_field(self::SECTION_SELF_CERTIFICATION,  
  325. Settings::FIELD_SELF_CERTIFICATION_FIELD_TITLE,  
  326. __('Self-certification field label', $this->_textdomain),  
  327. __('The label that will be displayed above the self-certification ' . 
  328. 'field at checkout. You can use the <code>{billing_country}</code> ' . 
  329. 'placeholder to automatically show the billing country chosen ' . 
  330. 'by the customer.',  
  331. $this->_textdomain),  
  332. 'title'); 
  333. // Currency 
  334. $this->render_dropdown_field(self::SECTION_CURRENCY,  
  335. Settings::FIELD_VAT_CURRENCY,  
  336. __('VAT Currency', $this->_textdomain),  
  337. get_woocommerce_currencies(),  
  338. __('EU regulations require that all payment and VAT amounts ' . 
  339. 'are indicated in the currency where your business is based. ' . 
  340. 'If you file your VAT reports in a currency different from ' . 
  341. 'shop\'s base currency, you can choose it here. ' . 
  342. '<strong>Important:</strong> all VAT data will be calculated and ' . 
  343. 'stored with the orders as they are created. We strongly recommend ' . 
  344. 'to double check the currency you have selected, as changing it later ' . 
  345. 'could result in incorrect VAT reports being generated.',  
  346. $this->_textdomain),  
  347. 'title'); 
  348.  
  349. // Exchange rates settings 
  350. $this->render_checkbox_field(self::SECTION_EXCHANGE_RATES_UPDATE,  
  351. Settings::FIELD_EXCHANGE_RATES_UPDATE_ENABLE,  
  352. __('Tick this box to enable automatic updating of exchange rates.', $this->_textdomain),  
  353. '', // No description required 
  354. ''); 
  355.  
  356. // Add "Exchange Rates Schedule" field 
  357. // Render the dropdown to allow choosing how often to update the Exchange Rates 
  358. $schedule_info = $this->_settings_controller->get_exchange_rates_schedule_info(); 
  359. $this->render_dropdown_field(self::SECTION_EXCHANGE_RATES_UPDATE,  
  360. Settings::FIELD_EXCHANGE_RATES_UPDATE_SCHEDULE,  
  361. __('Select how often you would like to update the exchange rates.', $this->_textdomain),  
  362. $this->_settings_controller->get_schedule_options(),  
  363. sprintf(__('<p>Last update: <span id="last_exchange_rates_update">%s</span>.</p>' . 
  364. '<p>Next update: <span id="next_exchange_rates_update">%s</span>.</p>',  
  365. $this->_textdomain),  
  366. $schedule_info['last_update'],  
  367. $schedule_info['next_update']),  
  368. 'exchange_rates_schedule'); 
  369. // Render the dropdown to choose the exchange rates provider 
  370. $this->render_dropdown_field(self::SECTION_EXCHANGE_RATES_UPDATE,  
  371. Settings::FIELD_EXCHANGE_RATES_PROVIDER,  
  372. __('Exchange rates provider', $this->_textdomain),  
  373. $this->_settings_controller->exchange_rates_providers_options(),  
  374. __('Select the Provider from which the exchange rates will be fetched.',  
  375. $this->_textdomain),  
  376. 'exchange_rates_provider'); 
  377. // Render the exchange rates table 
  378. $this->render_exchange_rates_fields(); 
  379.  
  380. // Sales 
  381. $this->render_dropdown_field(self::SECTION_SALE_RESTRICTIONS,  
  382. Settings::FIELD_SALE_DISALLOWED_COUNTRIES,  
  383. __('Prevent sales to these countries', $this->_textdomain),  
  384. wc()->countries->countries,  
  385. __('Here you can add a list of countries to which you do not want ' . 
  386. 'to sell. The countries in this list will not appear to the customer ' . 
  387. 'at any stage, thus preventing him from completing an order. Leave ' . 
  388. 'this field empty to allow sales to all countries configured in ' . 
  389. '<strong>WooCommerce > Settings</strong> section.',  
  390. $this->_textdomain),  
  391. 'multi_country_selector',  
  392. array('multiple' => 'multiple')); 
  393. // Sales 
  394. $woocommerce_tax_classes = $tax_classes = array_filter(array_map('trim', explode("\n", get_option('woocommerce_tax_classes')))); 
  395. $available_tax_classes = array( 
  396. // The "Standard" tax class actually has a blank key 
  397. '' => 'Standard',  
  398. ); 
  399. foreach($woocommerce_tax_classes as $tax_class_name) { 
  400. $available_tax_classes[sanitize_title($tax_class_name)] = $tax_class_name; 
  401. $this->render_dropdown_field(self::SECTION_REPORTS,  
  402. Settings::FIELD_TAX_CLASSES_EXCLUDED_FROM_MOSS,  
  403. __('The following tax classes should not be included in MOSS reports',  
  404. $this->_textdomain),  
  405. $available_tax_classes,  
  406. __('Here you can select one or more tax classes whose rates should ' . 
  407. 'be excluded from MOSS reports. The tax information for ' . 
  408. 'those rates will still be tracked, this setting will just ' . 
  409. 'be used to filter the data using the report filters ' . 
  410. 'in the <strong>Reports</strong> interface.',  
  411. $this->_textdomain),  
  412. 'moss_excluded_tax_classes',  
  413. array('multiple' => 'multiple')); 
  414. // Options 
  415. $this->render_text_field(self::SECTION_OPTIONS,  
  416. Settings::FIELD_VAT_ROUNDING_DECIMALS,  
  417. __('Decimals for VAT rounding', $this->_textdomain),  
  418. __('The amount of decimals to use when rounding VAT. This setting ' . 
  419. 'applies when the VAT evidence is generated (for example during ' . 
  420. 'the conversion of VAT totals to the appropriate VAT currency). ' . 
  421. 'If you are not sure of how many decimals you should use, please ' . 
  422. 'contact your Revenue office.',  
  423. $this->_textdomain),  
  424. 'numeric'); 
  425. $this->render_checkbox_field(self::SECTION_OPTIONS,  
  426. Settings::FIELD_COLLECT_VAT_DATA_FOR_MANUAL_ORDERS,  
  427. __('Collect VAT data for orders entered manually.', $this->_textdomain),  
  428. __('When this option is selected, the EU VAT Assistant will ' . 
  429. 'collect VAT data for orders that are entered manually by ' . 
  430. 'going to <em>WooCommerce > Orders > Add new order</em>. ' . 
  431. 'The data will be collected automatically, when the ' . 
  432. '"Calculate Totals" button is clicked.',  
  433. $this->_textdomain) . 
  434. '<br/><br/> ' . 
  435. '<strong>' . __('Important', $this->_textdomain) . '</strong>: ' . 
  436. __('The VAT data collected from manual orders will be the same ' . 
  437. 'collected from orders placed by customers ' . 
  438. 'and it will appear on the tax reports.', $this->_textdomain) . 
  439. ' ' . 
  440. __('Since the VAT MOSS scheme explicitly covers sales that do ' . 
  441. 'not require manual intervention, orders entered manually ' . 
  442. 'should fall outside the scope of such scheme.', $this->_textdomain) . 
  443. ' ' . 
  444. __('For this reason, this option is disabled by default. ' . 
  445. 'We recommend that you consult your accountant before enabling ' . 
  446. 'this option', $this->_textdomain),  
  447. ''); 
  448.  
  449.  
  450. // Debug 
  451. if(function_exists('wc_get_log_file_path')) { 
  452. $log_file_path = wc_get_log_file_path(Definitions::PLUGIN_SLUG); 
  453. else { 
  454. $log_file_path = sprintf('woocommerce/logs/%s-%s.txt', Definitions::PLUGIN_SLUG, sanitize_file_name(wp_hash(Definitions::PLUGIN_SLUG))); 
  455. $this->render_checkbox_field(self::SECTION_DEBUG,  
  456. Settings::FIELD_DEBUG_MODE,  
  457. __('Enable debug mode.', $this->_textdomain),  
  458. sprintf(__('When debug mode is enabled, the plugin will log ' . 
  459. 'events to file <code>%s</code>.', $this->_textdomain),  
  460. $log_file_path),  
  461. ''); 
  462.  
  463. /** 
  464. * Returns the title for the menu item that will bring to the plugin's 
  465. * settings page. 
  466. * @return string 
  467. */ 
  468. protected function menu_title() { 
  469. return __('EU VAT Assistant', $this->_textdomain); 
  470.  
  471. /** 
  472. * Returns the slug for the menu item that will bring to the plugin's 
  473. * settings page. 
  474. * @return string 
  475. */ 
  476. protected function menu_slug() { 
  477. return Definitions::MENU_SLUG; 
  478.  
  479. /** 
  480. * Returns the title for the settings page. 
  481. * @return string 
  482. */ 
  483. protected function page_title() { 
  484. return __('EU VAT Assistant - Settings', $this->_textdomain) . 
  485. sprintf(' (v. %s)', WC_Aelia_EU_VAT_Assistant::$version); 
  486.  
  487. /** 
  488. * Returns the description for the settings page. 
  489. * @return string 
  490. */ 
  491. protected function page_description() { 
  492. // TODO Restore link to documentation 
  493. return __('In this page you can configure the settings for the EU VAT Assistant plugin.',  
  494. $this->_textdomain); 
  495.  
  496. /*** Settings sections callbacks ***/ 
  497. public function checkout_section_callback() { 
  498. echo __('Here you can configure various parameters related to checkout.', $this->_textdomain); 
  499.  
  500. echo '<noscript>'; 
  501. echo __('This page requires JavaScript to work properly. Please enable JavaScript ' . 
  502. 'in your browser and refresh the page.</u>.',  
  503. $this->_textdomain); 
  504. echo '</noscript>'; 
  505.  
  506. public function self_certification_section_callback() { 
  507. echo __('Here you can decide to display an additional self-certification field that ' . 
  508. 'customers can use to confirm their country of residence.', $this->_textdomain); 
  509.  
  510. public function currency_section_callback() { 
  511. // Dummy 
  512.  
  513. public function exchange_rates_update_section_callback() { 
  514. // Dummy 
  515.  
  516. public function exchange_rates_section_callback() { 
  517. echo __('These exchange rates will be used to convert ' . 
  518. 'the order amounts (totals, VAT, etc) in the currency you use to file your VAT returns. ' . 
  519. '<strong>Important</strong>: you can enter the exchange rates manually, if you wish, but ' . 
  520. 'please make sure that they are in line with the values that your Revenue office would ' . 
  521. 'consider acceptable. The responsibility of ensuring that the rates are correct lies ' . 
  522. 'upon you. If you are in doubt, please contact your revenue office to determine which ' . 
  523. 'exchange rates they would consider acceptable. Most revenue offices have their own ' . 
  524. 'list of exchange rates, which you can enter here.', $this->_textdomain); 
  525. echo '<br /><br />'; 
  526. echo __('To set an exchange rate manually, tick the box next to the exchange rate field ' . 
  527. 'for the desired currency and enter the rate in the exchange rate field itself. ' . 
  528. 'The checkbox next to the "<strong>Set manually</strong>" label will select/deselect the checkboxes ' . 
  529. 'for all the currencies. <strong>Important</strong>: ensure that all exchange rates ' . 
  530. 'you flagged to be entered manually are filled. An empty exchange rate could lead to ' . 
  531. 'unpredictable results, as it\'s intepreted as zero.', $this->_textdomain); 
  532.  
  533. public function sale_restrictions_section_callback() { 
  534. // Dummy 
  535.  
  536. public function reports_section_callback() { 
  537. // Dummy 
  538.  
  539. public function options_section_callback() { 
  540. echo __('Miscellaneous options.', $this->_textdomain); 
  541.  
  542. public function links_section_callback() { 
  543. ?> 
  544. <div class="links"> 
  545. <p><?php 
  546. echo __('This section contains some convenient links to the ' . 
  547. 'sections of WooCommerce relevant to EU VAT compliance', $this->_textdomain); 
  548. ?></p> 
  549. <div class="settings"> 
  550. <h4 class="title"><?php 
  551. echo __('Settings', $this->_textdomain); 
  552. ?></h4> 
  553. <ul> 
  554. <li class="tax"> 
  555. <a href="<?php echo admin_url('admin.php?page=wc-settings&tab=tax'); ?>"><?php 
  556. echo __('Tax Settings', $this->_textdomain); 
  557. ?></a> 
  558. </li> 
  559. </ul> 
  560. </div> 
  561. <div class="reports"> 
  562. <h4 class="title"><?php 
  563. echo __('Reports', $this->_textdomain); 
  564. ?></h4> 
  565. <ul> 
  566. <li class="eu_vat_report"> 
  567. <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=taxes&report=eu_vat_by_country_report'); ?>"><?php 
  568. echo __('EU VAT By Country', $this->_textdomain); 
  569. ?></a> 
  570. </li> 
  571. <li class="vies_report"> 
  572. <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=taxes&report=vies_report'); ?>"><?php 
  573. echo __('VIES', $this->_textdomain); 
  574. ?></a> 
  575. </li> 
  576. <li class="intrastat_report"> 
  577. <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=taxes&report=intrastat_report'); ?>"><?php 
  578. echo __('INTRASTAT', $this->_textdomain); 
  579. ?></a> 
  580. </li> 
  581. <li class="sales_summary_report"> 
  582. <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=taxes&report=sales_summary_report'); ?>"><?php 
  583. echo __('Sales Summary (VAT RTD)', $this->_textdomain); 
  584. ?></a> 
  585. </li> 
  586. </ul> 
  587. </div> 
  588. </div> 
  589. <?php 
  590.  
  591. public function support_section_callback() { 
  592. echo '<div class="support_information">'; 
  593. echo '<p>'; 
  594. echo __('We designed this plugin to be robust and effective, ' . 
  595. 'as well as intuitive and easy to use. However, we are aware that, despite ' . 
  596. 'all best efforts, issues can arise and that there is always room for ' . 
  597. 'improvement.',  
  598. $this->_textdomain); 
  599. echo '</p>'; 
  600. echo '<p>'; 
  601. echo __('Should you need assistance, or if you just would like to get in touch ' . 
  602. 'with us, please use one of the links below.',  
  603. $this->_textdomain); 
  604. echo '</p>'; 
  605.  
  606. // Support links 
  607. echo '<ul id="contact_links">'; 
  608. echo '<li>' . sprintf(__('<span class="label">To request support</span>, please use our <a href="%s">Support portal</a>. ' . 
  609. 'The portal also contains a Knowledge Base, where you can find the ' . 
  610. 'answers to the most common questions related to our products.',  
  611. $this->_textdomain),  
  612. self::SUPPORT_URL) . '</li>'; 
  613. echo '<li>' . sprintf(__('<span class="label">To send us general feedback</span>, suggestions, or enquiries, please use ' . 
  614. 'the <a href="%s">contact form on our website.</a>',  
  615. $this->_textdomain),  
  616. self::CONTACT_URL) . '</li>'; 
  617. echo '</ul>'; 
  618.  
  619. echo '</div>'; 
  620.  
  621. public function debug_section_callback() { 
  622.  
  623. /*** Rendering methods ***/ 
  624. /** 
  625. * Renders the buttons at the bottom of the settings page. 
  626. */ 
  627. protected function render_buttons() { 
  628. parent::render_buttons(); 
  629. submit_button(__('Save and update exchange rates', $this->_textdomain),  
  630. 'secondary',  
  631. $this->_settings_key . '[update_exchange_rates_button]',  
  632. false); 
  633.  
  634. protected function render_exchange_rates_fields() { 
  635. // Prepare fields to display the Exchange Rate options for each selected currency 
  636. $exchange_rates_field_id = Settings::FIELD_EXCHANGE_RATES; 
  637. $exchange_rates = $this->current_settings($exchange_rates_field_id, $this->default_settings($exchange_rates_field_id, array())); 
  638. // Add "Exchange Rates" table 
  639. add_settings_field( 
  640. $exchange_rates_field_id,  
  641. '', // No label needed 
  642. array($this, 'render_exchange_rates_options'),  
  643. $this->_settings_key,  
  644. self::SECTION_EXCHANGE_RATES,  
  645. array( 
  646. 'settings_key' => $this->_settings_key,  
  647. 'exchange_rates' => $exchange_rates,  
  648. 'id' => $exchange_rates_field_id,  
  649. 'label_for' => $exchange_rates_field_id,  
  650. // Input field attributes 
  651. 'attributes' => array( 
  652. 'class' => $exchange_rates_field_id,  
  653. ),  
  654. ); 
  655.  
  656. /** 
  657. * Renders a table containing several fields that admins can use to configure 
  658. * the Exchange Rates for the various currencies. 
  659. * @param array args An array of arguments passed by add_settings_field(). 
  660. * @see add_settings_field(). 
  661. */ 
  662. public function render_exchange_rates_options($args) { 
  663. /** Generate the base field ID and field name that will be used to dynamically 
  664. * create the hierarchy of fields for the exchange rates. Every field will 
  665. * have a name like "base_field_id[currency]", so that PHP will automatically 
  666. * build a hierarchy out of them when the settings will be saved. 
  667. * Note: $base_field_id and $base_field_name are output parameters, they will 
  668. * be populated by the method. 
  669. */ 
  670. $this->get_field_ids($args, $base_field_id, $base_field_name); 
  671.  
  672. //var_dump($args);die(); 
  673. // Retrieve the enabled currencies 
  674. $currencies = $this->add_currency_labels($this->_settings_controller->enabled_currencies()); 
  675. // Retrieve the exchange rates 
  676. $exchange_rates = get_value(Settings::FIELD_EXCHANGE_RATES, $args, array()); 
  677. if(!is_array($exchange_rates)) { 
  678. //var_dump($exchange_rates);return; 
  679. throw new InvalidArgumentException(__('Argument "exchange_rates" must be an array.', $this->_textdomain)); 
  680.  
  681. // Retrieve the Currency used internally by WooCommerce 
  682. $vat_currency = $this->_settings_controller->vat_currency(); 
  683.  
  684. $html = '<table id="exchange_rates_settings">'; 
  685. // Table header 
  686. $html .= '<thead>'; 
  687. $html .= '<tr>'; 
  688. $html .= '<th class="currency_name">' . __('Currency', $this->_textdomain) . '</th>'; 
  689. $html .= '<th class="exchange_rate">' . __('Exchange Rate', $this->_textdomain) . '</th>'; 
  690. $html .= '<th class="set_manually">' . 
  691. __('Set Manually', $this->_textdomain) . 
  692. '<span class="help-icon" title="' . 
  693. __('Tick the box next to a currency if you would like to enter its ' . 
  694. 'exchange rate manually. By doing that, the rate you enter for ' . 
  695. 'that currency will not change, even if you have enabled the automatic ' . 
  696. 'update of exchange rates, below',  
  697. $this->_textdomain) . 
  698. '"></span>' . 
  699. '<div class="selectors">' . 
  700. '<span class="select_all">' . __('Select', $this->_textdomain) . '</span>' . 
  701. '/' . 
  702. '<span class="deselect_all">' . __('Deselect', $this->_textdomain) . '</span>' . 
  703. __('all', $this->_textdomain) . 
  704. '</div>' . 
  705. '</th>'; 
  706. $html .= '</th>'; 
  707.  
  708. $html .= '</tr>'; 
  709. $html .= '</thead>'; 
  710. $html .= '<tbody>'; 
  711.  
  712. // Render one line to display settings for base currency 
  713. $html .= $this->render_settings_for_vat_currency($vat_currency,  
  714. $currencies[$vat_currency],  
  715. $exchange_rates,  
  716. $base_field_id,  
  717. $base_field_name); 
  718.  
  719. foreach($currencies as $currency => $currency_name) { 
  720. // No need to render an Exchange Rate for main currency, as it would be 1:1 
  721. if($currency == $vat_currency) { 
  722. continue; 
  723.  
  724. $currency_field_id = $this->group_field($currency, $base_field_id); 
  725. $currency_field_name = $this->group_field($currency, $base_field_name); 
  726. $html .= '<tr>'; 
  727. // Output currency label 
  728. $html .= '<td class="currency_name">'; 
  729. $html .= "<span>$currency_name ($currency)</span>"; 
  730. $html .= '</td>'; 
  731.  
  732. $currency_settings = get_value($currency, $exchange_rates, array()); 
  733. $currency_settings = array_merge($this->_settings_controller->default_currency_settings(), $currency_settings); 
  734. //var_dump($currency_settings); 
  735.  
  736. // Render exchange rate field 
  737. $html .= '<td class="exchange_rate">'; 
  738. $field_args = array( 
  739. 'id' => $currency_field_id . '[rate]',  
  740. 'value' => get_value('rate', $currency_settings, ''),  
  741. 'attributes' => array( 
  742. 'class' => 'numeric',  
  743. ),  
  744. ); 
  745. ob_start(); 
  746. $this->render_textbox($field_args); 
  747. $field_html = ob_get_contents(); 
  748. ob_end_clean(); 
  749. $html .= $field_html; 
  750. $html .= '</td>'; 
  751.  
  752. //var_dump($currency_settings); 
  753. // Render "Set Manually" checkbox 
  754. $html .= '<td class="set_manually">'; 
  755. $field_args = array( 
  756. 'id' => $currency_field_id . '[set_manually]',  
  757. 'value' => 1,  
  758. 'attributes' => array( 
  759. 'class' => 'exchange_rate_set_manually',  
  760. 'checked' => get_value('set_manually', $currency_settings),  
  761. ),  
  762. ); 
  763. ob_start(); 
  764. $this->render_checkbox($field_args); 
  765. $field_html = ob_get_contents(); 
  766. ob_end_clean(); 
  767. $html .= $field_html; 
  768. $html .= '</td>'; 
  769.  
  770. // Render exchange rate markup field 
  771. //$html .= '<td>'; 
  772. //$field_args = array( 
  773. // 'id' => $currency_field_id . '[rate_markup]',  
  774. // 'value' => get_value('rate_markup', $currency_settings, ''),  
  775. // 'attributes' => array( 
  776. // 'class' => 'numeric',  
  777. // ),  
  778. //); 
  779. //ob_start(); 
  780. //$this->render_textbox($field_args); 
  781. //$field_html = ob_get_contents(); 
  782. //ob_end_clean(); 
  783. //$html .= $field_html; 
  784. //$html .= '</td>'; 
  785. $html .= '</tr>'; 
  786.  
  787. $html .= '</tbody>'; 
  788. $html .= '</table>'; 
  789.  
  790. echo $html; 
  791.  
  792. /** 
  793. * Renders a "special" row on the exchange rates table, which contains the 
  794. * settings for the base currency. 
  795. * @param string currency The currency to display on the row. 
  796. * @param string exchange_rates An array of currency settings. 
  797. * @param string base_field_id The base ID that will be assigned to the 
  798. * fields in the row. 
  799. * @param string base_field_id The base name that will be assigned to the 
  800. * fields in the row. 
  801. * @return string The HTML for the row. 
  802. */ 
  803. protected function render_settings_for_vat_currency($currency, $currency_name, $exchange_rates, $base_field_id, $base_field_name) { 
  804. $currency_field_id = $this->group_field($currency, $base_field_id); 
  805. $currency_field_name = $this->group_field($currency, $base_field_name); 
  806.  
  807. $html = '<tr>'; 
  808. // Output currency label 
  809. $html .= '<td class="currency_name">'; 
  810. $html .= "<span>$currency_name ($currency)</span>"; 
  811. $html .= '</td>'; 
  812.  
  813. $currency_settings = get_value($currency, $exchange_rates, array()); 
  814. $currency_settings = array_merge($this->_settings_controller->default_currency_settings(), $currency_settings); 
  815. //var_dump($currency_settings); 
  816.  
  817. // Render exchange rate field 
  818. $html .= '<td class="exchange_rate numeric">'; 
  819. $html .= '1'; // Exchange rate for base currency is always 1 
  820. $html .= '</td>'; 
  821.  
  822. // Render "Set Manually" checkbox 
  823. $html .= '<td>'; 
  824. $html .= '</td>'; 
  825.  
  826. // Render exchange rate markup field 
  827. //$html .= '<td>'; 
  828. //$html .= '</td>'; 
  829. $html .= '</tr>'; 
  830.  
  831. return $html;