diff --git a/html/ajax_misc.php b/html/ajax_misc.php index 4ab518a6c..d61894855 100644 --- a/html/ajax_misc.php +++ b/html/ajax_misc.php @@ -45,6 +45,7 @@ $http=new HttpInput(); try { $op= $http->request("op"); if ($op =='check_vatnumber') session_write_close(); + if ($op =='search_peppol') session_write_close(); } catch (\Exception $e) { exit(); @@ -376,6 +377,8 @@ $path = array( , 'email_setting'=>'ajax_email_setting' // check iban number , 'check_ibannumber'=>'ajax_check_ibannumber' + // related to peppol : search + ,'search_peppol'=>'ajax_search_peppol' ) ; if (array_key_exists($op, $path)) { diff --git a/html/js/ajax_fiche.js b/html/js/ajax_fiche.js index e0436f857..b603d121f 100644 --- a/html/js/ajax_fiche.js +++ b/html/js/ajax_fiche.js @@ -417,8 +417,52 @@ category_card.check_ibannumber = function (p_domid) { console.error(e.message); } } -category_card.search_peppol_participant=function(p_domid) { - + +/** + * Display a dialog box to search the PEPPOL ID of someone + * @parameter p_domid (string) ID of the DOM Element to update + */ +category_card.display_search_peppol = function (p_domid) +{ + try + { + var dgbox = "peppol_id_search_div"; + waiting_box(); + var queryString = { + op:'search_peppol' + ,ctl:p_domid + } + if (id$("peppol_id_search_div_frm")) { + queryString['query']=$F("query"); + queryString['filter']=$F("filter"); + } + + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'GET', + parameters: queryString, + onSuccess: function (req) { + remove_waiting_box(); + if (req.responseText == 'NOCONX') { + reconnect(); + return; + } + var y = calcy(15); + var div_style = "position:absolute;" + ";top:" + y + "px" + ";z-index:" + get_next_layer(); + add_div({id: dgbox, cssclass: 'inner_box', html: loading(), style: div_style, drag: false}); + $(dgbox).update( req.responseText); + + + } + } + ); + } catch (e) + { + alert_box(e.message); + } + } + //--> diff --git a/include/ajax/ajax_search_peppol.php b/include/ajax/ajax_search_peppol.php new file mode 100644 index 000000000..be5ad08b5 --- /dev/null +++ b/include/ajax/ajax_search_peppol.php @@ -0,0 +1,217 @@ + + +if (!defined('ALLOWED')) + die('Appel direct ne sont pas permis'); + +/** + * @file + * @brief search Peppol ID. + * + * Parameters : + * - query : string to search + * - ctl : DOMID to udpate (useless) + * - filter: query on name , VAT id or Enterprise ID + */ +$http = new HttpInput(); +try { + /* @var $query (string) string to search */ + $query = $http->request('query', 'string', ''); + + /* @$ctl_id (string) DOM ID of the element to update */ + $ctl_id = $http->request('ctl', 'string'); + + /* @filter (string) search on name, VAT ID or enterprise ID */ + $filter = $http->request('filter', 'string', ''); +} catch (Exception $e) { + echo $e->getMessage(); + return; +} + +/** + * @class + * @brief Found PEPPOL Elements, inner class + */ +class PEPPOL_Match_Record +{ + + var $participantID; + var array $docTypeID; + var $entity; +} + +class PEPPOL_Entity_Record +{ + var $name; + var $countryCode; + var $regDate; +} +$msg = _("La recherche par nom et numéro de TVA sont limitées à la Belgique"); + +echo \HtmlInput::title_box(_("Recherche PEPPOL Directory"), 'peppol_id_search_div'); +?> +
+
+

+ +

+ transform(["vatid" => _("Numéro de TVA"), "entid" => _("Numéro entreprise"), "name" => _("Nom")]); + $select_filter->selected = $filter + ?> +input() ?> + input() ?> + +
+'; // div class content + return; +} +//------------------------------------------------ +// if a query has been submitted, show the result +//------------------------------------------------ +$search = null; +switch ($filter) +{ + case 'name': + $search = http_build_query(["name" => $query, 'countryCode' => 'BE']); + break; + case "vatid": + if (stripos("x" . $query, "BE") == 0) + { + print _("Numéro de TVA invalide: doit commencer par BE"); + break; + } + $search = http_build_query(["participant" => 'iso6523-actorid-upis::9925:' . $query]); + break; + case 'entid': + if (strlen(trim($query ?? "")) != 10) + { + print _("Numéro entreprise belge valide: 10 chiffres"); + break; + } + $search = http_build_query(["participant" => 'iso6523-actorid-upis::0208:' . $query]); + break; + default: + throw new \Exception("ASP129 unknown filter",129); +} +$str = file_get_contents("https://directory.peppol.eu/search/1.0/xml?" . $search); +//$str= file_get_contents("/tmp/result.xml"); +$xml = new DOMDocument(); +$xml->loadXML($str); +$root = $xml->getElementsByTagName("resultlist"); +if (count($root) == 0) +{ + echo span(_("Aucun résultat"),' class="notice" '); + echo '
'; // div class content + return ; +} else +{ + printf(_("Résultat %d"), $root[0]->getAttribute("total-result-count")); +} + +$a_match = $xml->getElementsByTagName("match"); +$nb_match = $a_match->count(); + +$result=array(); +for ($i = 0; $i < $nb_match; $i++) +{ + $node = $a_match->item($i); + $obj = new PEPPOL_Match_Record(); + for ($e = 0; $e < $node->childElementCount; $e++) + { + if ($node->childNodes->item($e)->nodeType != XML_ELEMENT_NODE) + { + continue; + } + if ($node->childNodes->item($e)->tagName == 'participantID') + { + $obj->participantID = $node->childNodes->item($e)->textContent; + } elseif ($node->childNodes->item($e)->tagName == 'docTypeID') + { + $obj->docTypeID[] = $node->childNodes->item($e)->textContent; + } elseif ($node->childNodes->item($e)->tagName == 'entity') + { + $obj->entity = new PEPPOL_Entity_Record(); + for ($f=0;$f< $node->childNodes->item($e)->childElementCount;$f++) + { + if ( $node->childNodes->item($e)->childNodes->item($f)->tagName == 'name') + $obj->entity->name=$node->childNodes->item($e)->childNodes->item($f)->textContent; + if ($node->childNodes->item($e)->childNodes->item($f)->tagName=='countryCode') + $obj->entity->countryCode=$node->childNodes->item($e)->childNodes->item($f)->textContent; + if ($node->childNodes->item($e)->childNodes->item($f)->tagName=='regDate') + $obj->entity->regDate=$node->childNodes->item($e)->childNodes->item($f)->textContent; + } + + } + } + if ($obj->participantID != null) $result[]=clone $obj; + +} +if (empty($result)) +{ + echo span(_("Aucun résultat"),' class="notice" '); + return; +} + +//------------------------------------------------ +// display result +//------------------------------------------------ +$nb_result=count($result); +?> + + +
+
+ + participantID?> + +
+
+ entity->name?> + +
+
+'; // div class content +?> + \ No newline at end of file diff --git a/include/class/card_property.class.php b/include/class/card_property.class.php index 8f75afcc0..947955070 100644 --- a/include/class/card_property.class.php +++ b/include/class/card_property.class.php @@ -217,7 +217,10 @@ class Card_Property } if ( $this->ad_id == ATTR_DEF_PEPPOLID) { - + /// Propose a button to check VAT + $result['input']=new IPEPPOL_ID( "av_text" . $this->ad_id,$this->av_text); + $result['label']=$this->ad_text; + return $result; } if ($this->ad_id == ATTR_DEF_TVA) { diff --git a/include/lib/ipeppol_id.class.php b/include/lib/ipeppol_id.class.php new file mode 100644 index 000000000..368752a49 --- /dev/null +++ b/include/lib/ipeppol_id.class.php @@ -0,0 +1,86 @@ +itext = new IText($name,$value,$p_id); + $this->itext->title = _("PEPPOL_ID"); + $this->itext->placeholder = "9999:9999999999"; + $this->itext->extra = ""; + $this->itext->style = ' class="input_text" '; + $this->autofocus = false; + } + + function input() + { + if ( $this->readOnly==true) return $this->display(); + + $return = $this->itext->input(); + $return .= $this->button_check_peppol(); + $return.=sprintf('
',$this->itext->id); + return $return; + } + + public function getIText(): IText + { + return $this->itext; + } + + public function setIText(IText $itext): IPEPPOL_ID + { + $this->itext = $itext; + return $this; + } + + function button_check_peppol() + { + $button=new \IButton(uniqid()); + $button->javascript=sprintf("category_card.display_search_peppol('%s')", + $this->itext->id); + $button->extra='style="padding-bottom:0px"'; + $button->label=_("Vérifie"); + return $button->input(); + + + } + function display() + { + return $this->itext->display(); + + } + + static function testme() + { + $ivatnumber=new IPEPPOL_ID("av_text13"); + + echo $ivatnumber->input(); + } +} \ No newline at end of file diff --git a/sql/upgrade.sql b/sql/upgrade.sql index 4c4b03459..f6eeab669 100644 --- a/sql/upgrade.sql +++ b/sql/upgrade.sql @@ -16,7 +16,7 @@ update "parameter" set pr_id='MY_POSTCODE' where pr_id='MY_CP'; update "parameter" set pr_id='MY_CITY' where pr_id='MY_COMMUNE'; update "parameter" set pr_id='MY_COUNTRY' where pr_id='MY_PAYS'; -insert into attr_def (ad_id,ad_text,ad_type,ad_size,ad_search_followup,ad_default_order) values(55,'SIRENE','text',20,1,14); +insert into attr_def (ad_id,ad_text,ad_type,ad_size,ad_search_followup,ad_default_order) values(55,'SIREN','text',20,1,14); insert into attr_def (ad_id,ad_text,ad_type,ad_size,ad_search_followup,ad_default_order) values(56,'SIRET','text',20,1,15); insert into attr_def (ad_id,ad_text,ad_type,ad_size,ad_search_followup,ad_default_order) values(58,'PEPPOL ID','text',20,1,15); @@ -369,3 +369,106 @@ insert into profile_menu select me_code,'CFG',1,2,'E',0,(select distinct m2.pm_id from profile_menu m2 where m2.me_code='CFG' limit 1) from menu_ref where me_code='C0ML'; +create table parameter_internal (pi_id text not null primary key, pi_value text); +comment on table parameter_internal is 'Internal parameter, used by the application , it can''t not be changed by the interface'; + +create or replace function comptaproc.fill_internal_parameter() +returns text +as +$$ +declare + str_country text; + n_found int; +begin + select lower(pr_value) into str_country from "parameter" where pr_id = 'MY_COUNTRY'; + if str_country = 'belgique' or str_country = 'be' then + insert into parameter_internal values ('COUNTRY_CODE','BE') on conflict do nothing; + return 'BE'; + end if ; + if str_country = 'france' or str_country = 'fr' then + insert into parameter_internal values ('COUNTRY_CODE','FR') on conflict do nothing; + return 'FR'; + end if ; + + select 1 into n_found from bilan where b_file_template='document/fr_fr/fr_plan_abrege_perso_cr1000.form'; + + if n_found is NULL then + insert into parameter_internal values ('COUNTRY_CODE','BE') on conflict do nothing; + return 'BE'; + end if; + insert into parameter_internal values ('COUNTRY_CODE','FR') on conflict do nothing; + return 'FR'; +end; +$$ +language plpgsql; + +select comptaproc.fill_internal_parameter(); +-- insert new attributes for PEPPOL, SIREN and QUANTYTI +insert into jnt_fic_attr (fd_id,ad_id,jnt_order) + select f1.fd_id , 58,15 + from fiche_def f1 + join fiche_def f2 on (f1.fd_id=f2.fd_id) + where f2.frd_id in (8,9) + on conflict do nothing; + +insert into jnt_fic_attr (fd_id,ad_id,jnt_order) + select f1.fd_id , 57,16 + from fiche_def f1 + join fiche_def f2 on (f1.fd_id=f2.fd_id) + where f2.frd_id in (8,9) + on conflict do nothing; + +insert into jnt_fic_attr (fd_id,ad_id,jnt_order) + select f1.fd_id , 55,16 + from fiche_def f1 + join fiche_def f2 on (f1.fd_id=f2.fd_id) + where f2.frd_id in (8,9) + on conflict do nothing; + +insert into jnt_fic_attr (fd_id,ad_id,jnt_order) + select f1.fd_id , 59,90 + from fiche_def f1 + join fiche_def f2 on (f1.fd_id=f2.fd_id) + where f2.frd_id in (1,2) + on conflict do nothing; + +-- Add a attribute PEPPOL ID for customer and supplier in Belgium only +-- for the card category +-- Plus, compute a default value +-- +CREATE OR REPLACE FUNCTION comptaproc.update_peppol () + RETURNS int2 + /*- SETOF menu_tree : (TABLE FUNCTION) menu_tree is a type of a rowtype create type menu_tree as (code text,description text); + - int2, text,varchar... + - trigger : if called from a trigger + - void : nothing + - boolean + */ AS +$BODY$ +declare +/* + * Section for variables + */ +n_card_id int; +vat_number text; +record_card RECORD; +result_fct int; +begin + +result_fct := 0; + +for record_card in select * from fiche_detail where ad_id=13 and LOWER (ad_value ) like 'be%' +loop + vat_number := regexp_replace(record_card.ad_value,'\D','','g'); + if length(vat_number) = 10 then + update fiche_detail set ad_value = '0208:'||vat_number where f_id=record_card.f_id and ad_id=58; + RESULT_fct := result_fct + 1; + end if; +end loop; + +return result_fct; +end; +$BODY$ +LANGUAGE plpgsql; + +select comptaproc.update_peppol(); \ No newline at end of file