1<?php
2/**
3 * @package Horde
4 */
5class Horde_Block_Vatid extends Horde_Core_Block
6{
7    /**
8     */
9    public function __construct($app, $params = array())
10    {
11        parent::__construct($app, $params);
12
13        $this->enabled = Horde_Util::loadExtension('soap');
14        $this->_name = _("EU VAT identification");
15    }
16
17    /**
18     */
19    protected function _title()
20    {
21        return _("VAT id number verification");
22    }
23
24    /**
25     */
26    protected function _content()
27    {
28        global $page_output;
29
30        $name = strval(new Horde_Support_Randomid());
31
32        $page_output->addScriptFile('vatid.js', 'horde');
33        $page_output->addInlineScript(array(
34            '$("' . $name . '").observe("submit", HordeBlockVatid.onSubmit.bindAsEventListener(HordeBlockVatid))'
35        ), true);
36
37        return '<form style="padding:2px" action="' .
38            $this->_ajaxUpdateUrl() . '" id="' . $name . '">' .
39            Horde_Util::formInput() .
40            Horde::label('vatid', _("VAT identification number:")) .
41            '<br /><input type="text" length="14" name="vatid" />' .
42            '<br /><input type="submit" id="vatbutton" value="' . _("Check") .
43            '" class="horde-default" /> ' .
44            Horde_Themes_Image::tag('loading.gif', array(
45                'alt' => _("Checking"),
46                'attr' => array('style' => 'display:none')
47            )) .
48            '<div class="vatidResults"></div>' .
49            '</form>';
50    }
51
52    /**
53     */
54    protected function _ajaxUpdate(Horde_Variables $vars)
55    {
56        $html = '';
57        $vatid = str_replace(' ', '', $vars->vatid);
58
59        if (empty($vatid) ||
60            !preg_match('/^([A-Z]{2})([0-9A-Za-z\+\*\.]{2,12})$/', $vatid, $matches)) {
61            return '<br />' . $this->_error(_("Invalid VAT identification number format."));
62        }
63
64        if (empty($matches)) {
65            return;
66        }
67
68        try {
69            $client = new SoapClient(
70                'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl',
71                array('exceptions' => true));
72            $result = $client->checkVat(array(
73                'countryCode' => $matches[1],
74                'vatNumber' => $matches[2]
75            ));
76
77            if ($result->valid) {
78                $html .= '<span style="color:green;font-weight:bold">'
79                    . _("This VAT identification number is valid.")
80                    . '</span><br />';
81            } else {
82                $html .= $this->_error(_("This VAT identification number is invalid.")) . '<br />';
83            }
84
85            $html .= '<em>' . _("Country") . ':</em> '
86                . $result->countryCode . '<br /><em>'
87                . _("VAT number") . ':</em> ' . $result->vatNumber
88                . '<br /><em>' . _("Date") . ':</em> '
89                . strftime($GLOBALS['prefs']->getValue('date_format'), strtotime($result->requestDate))
90                . '<br />';
91
92            if (!empty($result->name)) {
93                $html .= '<em>' . _("Name") . ':</em> ' . $result->name . '<br />';
94            }
95
96            if (!empty($result->address)) {
97                $html .= '<em>' . _("Address") . ':</em> ' . $result->address . '<br />';
98            }
99        } catch (SoapFault $e) {
100            $error = $e->getMessage();
101
102            switch (true) {
103            case strpos($error, 'INVALID_INPUT'):
104                $error = _("The provided country code is invalid.");
105                break;
106
107            case strpos($error, 'SERVICE_UNAVAILABLE'):
108                $error = _("The service is currently not available. Try again later.");
109                break;
110
111            case strpos($error, 'MS_UNAVAILABLE'):
112                $error = _("The member state service is currently not available. Try again later or with a different member state.");
113                break;
114
115            case strpos($error, 'TIMEOUT'):
116                $error = _("The member state service could not be reached in time. Try again later or with a different member state.");
117                break;
118
119            case strpos($error, 'SERVER_BUSY'):
120                $error = _("The service is currently too busy. Try again later.");
121                break;
122            }
123
124            $html .= $this->_error($error);
125        }
126
127        return $html;
128    }
129
130    /**
131     */
132    private function _error($text)
133    {
134        return '<span style="color:red;font-weight:bold">' . $text . '</span>';
135    }
136
137}
138