diff --git a/html/ajax_misc.php b/html/ajax_misc.php index d61894855..b926f4ccb 100644 --- a/html/ajax_misc.php +++ b/html/ajax_misc.php @@ -379,6 +379,8 @@ $path = array( , 'check_ibannumber'=>'ajax_check_ibannumber' // related to peppol : search ,'search_peppol'=>'ajax_search_peppol' + // find and select a VATEX code : VAT Exemption code mandatory for PEPPOL + ,'search_vatex'=>'ajax_search_vatex' ) ; if (array_key_exists($op, $path)) { @@ -596,7 +598,7 @@ EOF; $Res = $cn->exec_sql("select * from v_tva_rate where - tva_purchase <> '#' and tva_sale <> '#' + tva_purchase <> '#' or tva_sale <> '#' order by tva_id asc"); } $Max = Database::num_row($Res); diff --git a/html/css/style-classic7.css b/html/css/style-classic7.css index aeb0271b2..3f35c6f12 100644 --- a/html/css/style-classic7.css +++ b/html/css/style-classic7.css @@ -1266,8 +1266,8 @@ div.inner_box { border:1px solid #00008B; -moz-box-shadow: 10px 10px 5px #888; box-shadow: 15px 15px 15px #888; - font-size:90%; - font-size:0.9rem; + font-size:100%; + font-size:1rem; width: 100%; left:0px ; } @@ -1285,8 +1285,8 @@ div.inner_box { border:1px solid #00008B; -moz-box-shadow: 10px 10px 5px #888; box-shadow: 15px 15px 15px #888; - font-size:90%; - font-size:0.9rem; + font-size:100%; + font-size:1rem; width: 50%; left:22% ; } @@ -1340,6 +1340,10 @@ div.inner_box { border-radius: 7px; } } + +div.inner_box div.content,div.inner_box2 div.content { + padding:5px; +} /***********************************************************************************/ div.op_detail_title { background-color:#888; @@ -3519,7 +3523,18 @@ margin:1px; .nav-level2 .active { border-radius:0px !important; } - +/******************************************/ +/* MENU LEVEL > 3 */ +/******************************************/ +.nav-level4{ + --border-size:2px; +} +.nav-level4 .nav-item:hover{ + background-color: aliceblue; +} +.nav-level4 .active { + background-color: aliceblue; +} /****************************************/ /* Module for smartphone menu */ /***************************************/ diff --git a/html/do.php b/html/do.php index e09e51cbc..7db6f5f2a 100644 --- a/html/do.php +++ b/html/do.php @@ -281,7 +281,8 @@ if (isset($_REQUEST['ac'])) // Show module and highligt selected one show_module($module_id); - + global $level; + $level = 0; show_menu( $amenu_id[0]['pm_id_v3']); show_menu( $amenu_id[0]['pm_id_v2']); diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 57fb48df1..f23e31f10 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -2050,3 +2050,199 @@ var operation_exercice = { } } } + + +var Supplement_Document={ + +}; +/** + * see ledger_detail_sup_files.php + * $rowid=sprintf("row_js_%s_%s",$div,$item->js_id); + * @param {int} nDossier + * @param {string} sDiv + * @param {int} nJS_ID + * @returns {void} + */ +Supplement_Document.delete_document=function (nDossier,sDiv,nJS_ID,nJR_ID) +{ + confirm_box(null + ,content[47] + ,function (){ + try + { + var queryString = { + gDossier:nDossier, + div:sDiv, + jr_id:nJR_ID, + js_id:nJS_ID, + op:"ledger", + act:"rmsup" + }; + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'POST', + parameters: queryString, + onSuccess: function (req) { + remove_waiting_box(); + if (req.responseText == 'NOCONX') { + reconnect(); + return; + } + id$("row_js_"+sDiv+"_"+nJS_ID).remove(); + + } + } + ); + } catch (e) + { + alert_box(e.message); + } + } + ); + +} +Supplement_Document.input_file=function(nDossier,sDiv,nJR_ID) +{ + try + { + var dgbox = "sup_doc_input_file"+sDiv; + waiting_box(); + removeDiv(dgbox); + var queryString = { + gDossier:nDossier, + div:sDiv, + jr_id:nJR_ID, + op:"ledger", + act:"input_file", + dgbox:dgbox + }; + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'GET', + parameters: queryString, + onFailure: ajax_misc_failure, + 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_box2', html: loading(), style: div_style, drag: true}); + $(dgbox).innerHTML = req.responseText; + + } + } + ); + } catch (e) + { + alert_box(e.message); + } + +} +/** + * + * @param {string} FORM ID + * @returns {Boolean} + */ +Supplement_Document.save_file=function(form_dom_id) +{ + try + { + waiting_box(); + var form_data=$(form_dom_id).serialize(); + var xhr = new XMLHttpRequest(); + var div=id$(form_dom_id).elements["div"].value; + // check size + var total_size=0; + var file_to_upload=id$("doc_sup"); + var max_size=id$(form_dom_id).elements["MAX_FILE_SIZE"].value; + var post_max_size=id$(form_dom_id).elements["post_max_size"].value; + var feedback_div=id$('feedback'+div); + + for (var e=0;e max_size) { + // if size > accepted size , push filename with error in an array feedback, + feedback_div.innerHTML += '

' + file_to_upload.files[e].name + +content[78]+ "

"; + remove_waiting_box(); + return false; + } else if ( total_size+file_to_upload.files[e].size >= post_max_size ) + { + feedback_div.innerHTML += '

limite '+content[78]+"

"; + remove_waiting_box(); + return false; + } + else { + total_size+=file_to_upload.files[e].size; + } + } + feedback_div.innerHTML="loading...."; + document.getElementById("progress_upload1b").setAttribute("value", 0); + + xhr.upload.onprogress = function (e) { + document.getElementById("progress_upload1b").setAttribute("max", e.total) + "
"; + document.getElementById("progress_upload1b").setAttribute("value", e.loaded) + "
"; + + } + + xhr.onreadystatechange = function (event) { + if (this.readyState == XMLHttpRequest.DONE) + { + remove_waiting_box(); + + if (this.status === 200) { + document.getElementById("supplement_div_list"+div).innerHTML += this.responseText ; + let dgbox=id$(form_dom_id).elements["dgbox"].value; + removeDiv(dgbox); + + } else { + document.getElementById("supplement_div_list"+div).innerHTML += "status" + this.statusText + "
"; + } + } + } + + xhr.open("POST", "ajax_misc.php?"+form_data, true); + // works xhr.send(new FormData(input.parentElement)); + var formData = new FormData(document.getElementById(form_dom_id)); + xhr.send(formData); + }catch(e) + { + console.error("Supplement_Document.save_file "+e.message) + } + remove_waiting_box(); + return false; +} +Supplement_Document.refresh_list=function (nDossier,sDiv,nJR_id) +{ + try + { + var queryString = { + gDossier:nDossier, + div:sDiv, + jr_id:nJR_id, + op:"ledger", + act:"refresh_file" + }; + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'GET', + parameters: queryString, + onSuccess: function (req) { + $("supplement_div_list"+sDiv).update(req.responseText); + + } + } + ); + } catch (e) + { + console.error(e.message); + } + +} diff --git a/html/js/accounting_item.js b/html/js/accounting_item.js index 9c261a847..d8f18af0a 100644 --- a/html/js/accounting_item.js +++ b/html/js/accounting_item.js @@ -45,7 +45,7 @@ function search_accounting(obj) sx=document.body.scrollTop+60; } - var div_style="top:"+sx+"px"; + var div_style="top:"+sx+"px"+';z-index:'+get_next_layer(); removeDiv('search_account'); add_div({id:'search_account',cssclass:'inner_box',html:loading(),style:div_style,drag:false}); @@ -234,7 +234,7 @@ function errorPoste() function display_all_card(p_dossier,p_accounting) { waiting_box(); - var div_dest=add_div({id:'info_card_accounting',cssclass:"inner_box",style:fixed_position(100,250)+";width:auto"}); + var div_dest=add_div({id:'info_card_accounting',cssclass:"inner_box",style:fixed_position(100,250)+";width:auto;z-index:"+get_next_layer()}); var action=new Ajax.Request ( 'ajax_misc.php', { method:'get', diff --git a/html/js/ajax_fiche.js b/html/js/ajax_fiche.js index b603d121f..63144c87d 100644 --- a/html/js/ajax_fiche.js +++ b/html/js/ajax_fiche.js @@ -428,9 +428,14 @@ category_card.display_search_peppol = function (p_domid) { var dgbox = "peppol_id_search_div"; waiting_box(); + let peppol_id=id$(p_domid).value; var queryString = { op:'search_peppol' ,ctl:p_domid + ,query:peppol_id + } + if ( peppol_id != "") { + queryString['filter']='peppolid'; } if (id$("peppol_id_search_div_frm")) { queryString['query']=$F("query"); diff --git a/html/js/card.js b/html/js/card.js index f82a039a4..2ec564ba0 100644 --- a/html/js/card.js +++ b/html/js/card.js @@ -116,7 +116,7 @@ function search_card(obj) if ( document.getElementById('search_card') ) { removeDiv('search_card'); } - + waiting_box(); @@ -464,7 +464,7 @@ function result_card_search(req) sx=document.body.scrollTop+60; } - var div_style="top:"+sx+"px;min-height:80%;height:auto"; + var div_style="top:"+sx+"px;min-height:80%;height:auto;z-index:"+get_next_layer();; add_div({id:'search_card',cssclass:'inner_box',html:"",style:div_style,drag:false,effect:'blinddown'}); id$('search_card').innerHTML=code_html; @@ -690,7 +690,7 @@ function select_card_type(obj) var sx=0; sx=calcy(160); - var str_style="top:"+sx+"px;height:auto"; + var str_style="top:"+sx+"px;height:auto;z-index:"+get_next_layer(); waiting_box(); var popup={'id': content,'cssclass':'inner_box','style':str_style,'html':"",'drag':false}; @@ -782,7 +782,7 @@ function dis_blank_card(obj) var content='div_new_card'; var nTop=calcy(150); var nLeft=posX; - var str_style="top:"+nTop+"px;right:"+nLeft+"px;height:auto;width:45rem;"; + var str_style="top:"+nTop+"px;right:"+nLeft+"px;height:auto;width:45rem;z-index:"+get_next_layer(); var popup={'id': content,'cssclass':'inner_box','style':str_style,'html':loading(),'drag':false}; @@ -824,7 +824,7 @@ function form_blank_card(obj) var content='div_new_card'; var nTop=posY-40; var nLeft=posX-20; - var str_style="top:"+nTop+"px;left:"+nLeft+"px;width:60em;height:auto"; + var str_style="top:"+nTop+"px;left:"+nLeft+"px;width:60em;height:auto;z-index:"+get_next_layer(); var popup={'id': content,'cssclass':'inner_box','style':str_style,'html':loading(),'drag':true}; if ( document.getElementById(content)) {removeDiv(content);} diff --git a/html/js/infobulle.js b/html/js/infobulle.js index b91744b65..dc28cbb61 100644 --- a/html/js/infobulle.js +++ b/html/js/infobulle.js @@ -94,9 +94,13 @@ function displaySelectBox(p_name) { } newDiv.innerHTML=id$("select_box"+p_name).innerHTML; var viewport = document.viewport.getDimensions(); + let div_height=newDiv.getHeight(); + if ( div_height > window.innerHeight) { + div_height = window.innerHeight / 2; + } var locPosY=posY; - if ( posY+offsetY+ newDiv.getHeight() > window.innerHeight -3) { - locPosY-=newDiv.getHeight()+20 + if ( posY+offsetY+ div_height > window.innerHeight -3) { + locPosY-=div_height+20 } newDiv.style.top=locPosY+"px"; @@ -112,7 +116,7 @@ function displaySelectBox(p_name) { id$("search_"+p_name+"_t_list").focus(); } } catch(e) { - alert(e.message); + console.error(e.message); } } diff --git a/html/js/managetable.js b/html/js/managetable.js index 8026f1e21..9407b20a7 100644 --- a/html/js/managetable.js +++ b/html/js/managetable.js @@ -381,6 +381,7 @@ var ManageTable = function (p_table_name) var pos = calcy(50); here.mt_style["top"]=pos+"px"; + here.mt_style["z-index"]=get_next_layer(); $(obj.id).setStyle(here.mt_style); remove_waiting_box(); $(obj.id).update(x['html']); diff --git a/html/js/noalyss_script.js b/html/js/noalyss_script.js index bc01d7b7f..afab017e5 100644 --- a/html/js/noalyss_script.js +++ b/html/js/noalyss_script.js @@ -609,14 +609,19 @@ function popup_select_tva(obj, p_function_callback) { if (document.getElementById('tva_select')) { removeDiv('tva_select'); } - - var queryString = "gDossier=" + obj.gDossier + "&op=dsp_tva" + "&ctl=" + obj.ctl + '&popup=' + 'tva_select'; - if (obj.jcode) - queryString += '&code=' + obj.jcode; - if (obj.compute) - queryString += '&compute=' + obj.compute; - if (obj.filter) - queryString += '&filter=' + obj.filter; + var gDossier=(obj.gDossier)?obj.gDossier:obj.getAttribute("gdossier"); + var ctl=(obj.ctl)?obj.ctl:obj.getAttribute("ctl"); + + var queryString = "gDossier=" + gDossier + "&op=dsp_tva" + "&ctl=" + ctl + '&popup=' + 'tva_select'; + + var jcode=(obj.jcode)?obj.jcode:obj.getAttribute("jcode"); + if (jcode) + queryString += '&code=' + jcode; + var compute=(obj.compute)?obj.compute:obj.getAttribute("compute"); + if (compute) queryString += '&compute=' + compute; + var filter=(obj.filter)?obj.filter:obj.getAttribute("filter"); + + if (filter) queryString += '&filter=' + filter; var action = new Ajax.Request( "ajax_misc.php", @@ -641,7 +646,7 @@ function popup_select_tva(obj, p_function_callback) { var nTop = posY - 200; var nLeft = "15%"; - var str_style = "top:" + nTop + "px;left:" + nLeft + ";right:" + nLeft + ";width:55em;height:auto"; + var str_style = "top:" + nTop + "px;left:" + nLeft + ";right:" + nLeft + ";width:55em;height:auto;z-index:"+get_next_layer()+';'; var popup = { 'id': 'tva_select', @@ -1135,6 +1140,8 @@ function show_calc() { if (document.getElementById('calc1')) { this.document.getElementById('inp').value = ""; this.document.getElementById('inp').focus(); + document.getElementById("calc1").setStyle({ 'z-index':get_next_layer()}); + return; } var sid = 'calc1'; @@ -1147,8 +1154,10 @@ function show_calc() { shtml += ' ' + content[67] + ' '; var obj = { - id: sid, html: shtml, - drag: false, style: 'z-index:'+get_next_layer() + id: sid, + html: shtml, + drag: false, + style: 'z-index:'+get_next_layer() }; add_div(obj); this.document.getElementById('inp').focus(); @@ -2202,10 +2211,11 @@ function view_action(ag_id, dossier, modify) { * @param _id : id of the table * @param colnr : string containing the column number where you're searching separated by a comma * @param start_row : first row (1 if you have table header) + * @param class 2nd filter on the CSS CLASS of the row (TR), domid of the TAG containing the classname (TagName: SELECT, HIDDEN, TEXT ) * @returns nothing * @see HtmlInput::filter_table */ -function filter_table(phrase, _id, colnr, start_row) { +function filter_table(phrase, _id, colnr, start_row,classname) { id$('info_div').innerHTML = content[65]; id$('info_div').style.display = "block"; var words = id$(phrase).value.toLowerCase(); @@ -2220,8 +2230,17 @@ function filter_table(phrase, _id, colnr, start_row) { } var ele; var tot_found = 0; - - for (var r = start_row; r < table.rows.length; r++) { + console.debug(`filter is ${classname}`) + var row_class=""; + if ( classname ) row_class=id$(classname).value; + + for (var r = start_row; r < table.rows.length; r++) + { + if ( row_class != "" && ! table.rows[r].hasClassName(row_class)) { + console.debug(`no check ${r} ${classname}`) + continue; + } + console.debug(`checked ${r} ${classname}`) var found = 0; for (var col = 0; col < aCol.length; col++) { var idx = aCol[col]; @@ -4992,4 +5011,114 @@ Noalyss.prototype.parameter_test_smtp = function () } +VAT_Code = function (dossier_id) { + this.dossier_id=dossier_id; +} + +VAT_Code.prototype.list_vatex=function () +{ + try + { + var here=this; + var dgbox = "search_vatex_div"; + waiting_box(); + removeDiv(dgbox); + var queryString = { + op:'search_vatex', + gDossier:this.dossier_id, + dgbox:dgbox + } + 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); + here.filter_country(); + + } + } + ); + } catch (e) + { + alert_box(e.message); + } + +} + +VAT_Code.prototype.select_value=function(vx_code) +{ + try + { + var dgbox = "search_vatex_div"; + waiting_box(); + var queryString = { + op:'search_vatex', + gDossier:this.dossier_id, + select_code:vx_code, + dgbox:dgbox + + } + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'GET', + parameters: queryString, + onSuccess: function (req) { + remove_waiting_box(); + if (req.responseText == 'NOCONX') { + reconnect(); + return; + } + removeDiv(dgbox); + var answer=req.responseJSON + $("vx_code").value=answer.vx_code; + $("vx_value").update(answer.vx_value); + $('vx_code_description').update(answer.vx_description) + + + } + } + ); + } catch (e) + { + alert_box(e.message); + } + +} +VAT_Code.prototype.filter_country=function() +{ + try { + var to_show=id$("filter_country").value; + console.debug(`show ${to_show}`) + let a_row=id$("code_vatex_tb").rows; + // show all rows, then hide + for (let i=1;i< a_row.length;i++) { + + if (id$("filter_country").value == 0 || a_row[i].hasClassName(to_show)){ + a_row[i].show() + console.debug(`show row ${i}`) + + }else { + a_row[i].hide() + console.debug(`hide row ${i}`) + } + } + $('lk_code_vatex_tb').value=""; + }catch (e) + { + console.error(e.message); + return false; + } +} noalyss=new Noalyss(); + diff --git a/include/XMLDocument/document_reference_type.class.php b/include/XMLDocument/document_reference_type.class.php new file mode 100644 index 000000000..855cdde2f --- /dev/null +++ b/include/XMLDocument/document_reference_type.class.php @@ -0,0 +1,90 @@ +filecontent + . ", mimecode=" . $this->mimecode + . ", filename=" . $this->filename + . "]"; + } +} + +class Document_Reference +{ + protected $id; + protected $description; + protected Binary_Object $binary_object; + function __toString(): string + { + return "Document_Reference[id=" . $this->id + . ", description=" . $this->description + . ", binary_object=" . $this->binary_object + . "]"; + } + public function getId() + { + return $this->id; + } + + public function getDescription() + { + return $this->description; + } + + public function getBinary_object(): Binary_Object + { + return $this->binary_object; + } + + public function setId($id) + { + $this->id = $id; + return $this; + } + + public function setDescription($description) + { + $this->description = $description; + return $this; + } + + public function setBinary_object(Binary_Object $binary_object) + { + $this->binary_object = $binary_object; + return $this; + } + + + +} \ No newline at end of file diff --git a/include/XMLDocument/invoiceubl21.class.php b/include/XMLDocument/invoiceubl21.class.php index 6f8db429f..c7f123ad5 100644 --- a/include/XMLDocument/invoiceubl21.class.php +++ b/include/XMLDocument/invoiceubl21.class.php @@ -83,6 +83,17 @@ class InvoiceUBL21 extends XMLInvoice { $a_error[]=$item; } } + /** + * check that PEPPOL ID is valid + */ + if ( isset($company['COMPANY_UBL_ID'])) + { + if ( strpos($company['COMPANY_UBL_ID'],':') == 0 ) + { + $a_error[]="COMPANY_UBL_ID"; + } + + } return $a_error; } /** @@ -100,11 +111,23 @@ class InvoiceUBL21 extends XMLInvoice { ]; foreach ($a_needed as $item=>$value) { - if ( $this->data['customer'][$value]=="") { + if ( trim($this->data['customer'][$value])=="") { $a_error[]=$value; } } - + if ( $this->data['customer']["endpoint_id"] != "") + { + // check if peppol id has the form 9999:9999... + list($scheme_id,$peppol)=explode(":", $this->data['customer'][$value]); + if (preg_replace('/[0-9]/', '', $scheme_id) != "") + { + $a_error[]=ATTR_DEF_PEPPOLID; + }elseif(\noalyss_trim($peppol) =="") + { + $a_error[]=ATTR_DEF_PEPPOLID; + + } + } return $a_error; } @@ -130,9 +153,10 @@ class InvoiceUBL21 extends XMLInvoice { $customer=$this->createElement('cac:AccountingCustomerParty'); $customer_party=$customer->appendChild($this->createElement('cac:Party')); - ///@todo EndPointID doit être dans les paramètres (voir upgrade.sql) - $customer_party->appendChild($this->createElement('cbc:EndpointID',$this->data['customer']['endpoint_id'])) - ->setAttribute('schemeID', 9925); + list($scheme_id,$peppol)=explode( ":",$this->data['customer']['endpoint_id']); + $customer_party->appendChild($this->createElement('cbc:EndpointID',$peppol)) + ->setAttribute('schemeID', $scheme_id); + $party_name=$this->createElement('cac:PartyName'); $party_name->appendChild($this->createElement("cbc:Name", $this->data['customer']['name'])); $customer_party->appendChild($party_name); @@ -210,7 +234,11 @@ class InvoiceUBL21 extends XMLInvoice { $supplier=$this->createElement('cac:AccountingSupplierParty'); $supplier_party=$supplier->appendChild($this->createElement('cac:Party')); - $supplier_party->appendChild($this->createElement('cbc:EndpointID',$this->data["supplier"]['supplier_vat_id']))->setAttribute('schemeID', 9925); + list($scheme_id,$peppol)=explode( ":",$company['COMPANY_UBL_ID']); + $supplier_party->appendChild($this->createElement('cbc:EndpointID',$peppol)) + ->setAttribute('schemeID', $scheme_id); + + //$supplier_party->appendChild($this->createElement('cbc:EndpointID',$this->data["supplier"]['supplier_vat_id']))->setAttribute('schemeID', 9925); $party_name=$this->createElement('cac:PartyName'); $party_name->appendChild($this->createElement('cbc:Name', $this->data['supplier']['name'])); $supplier_party->appendChild($party_name); @@ -269,6 +297,7 @@ class InvoiceUBL21 extends XMLInvoice { S 6 + if ID !=Z and ID != S VAT @@ -292,12 +321,14 @@ class InvoiceUBL21 extends XMLInvoice { $subTotalXML->appendChild($this->createElement('cbc:TaxAmount',sprintf("%.2f",$subTotal[$i]['vat']))) ->setAttribute("currencyID",$this->data['currency']); $taxCategory=$this->createElement("cac:TaxCategory"); - /** - * @TODO DNY - * Pas toujours S !? - */ $taxCategory->appendChild($this->createElement("cbc:ID",$subTotal[$i]['vat_code'])); $taxCategory->appendChild($this->createElement("cbc:Percent",sprintf("%.2f",$subTotal[$i]['percent']))); + if ($subTotal[$i]['vat_code'] != "S" + && $subTotal[$i]['vat_code'] != "Z") + { + // if cbc:ID not S and not Z then exemption VAT code is needed + $taxCategory->appendChild($this->createElement("cbc:TaxExemptionReasonCode",$subTotal[$i]['vatex'])); + } $taxScheme=$this->createElement("cac:TaxScheme"); $taxScheme->appendChild($this->createElement("cbc:ID", "VAT")); $taxCategory->appendChild($taxScheme); diff --git a/include/XMLDocument/xml_reader.class.php b/include/XMLDocument/xml_reader.class.php new file mode 100644 index 000000000..f4d458c2a --- /dev/null +++ b/include/XMLDocument/xml_reader.class.php @@ -0,0 +1,571 @@ +domDocument = $domDocument; + $this->xpath = new \DOMXPath($this->domDocument); + } + /** + * @brief before executing xpath->query the namespace must be registered + * the NS are different for each type of doc + * @param $xml (null , DOMXPath simpleXML) + */ + public function registerNS($xml=null) + { + $a_namespace=$this->get_namespace(); + if ($xml == null) + { + foreach ($a_namespace as $pf=>$ns) { + $this->xpath->registerNamespace($pf,$ns); + } + } + elseif ( get_class($xml) == "SimpleXMLElement" ) + { + foreach ($a_namespace as $pf=>$ns) { + $xml->registerXPathNamespace($pf,$ns); + } + } + elseif (get_class($xml) == "DOMXPath" ) + { + foreach ($a_namespace as $pf=>$ns) { + $xml->registerNamespace($pf,$ns); + } + + } + else + { + throw new \Exception ("unknown object ".get_class($xml),57); + } + } + /** + * + * @return \DOMDocument + */ + public function get_domDocument(): \DOMDocument + { + return $this->domDocument; + } + + public function get_xpath(): \DOMXPath + { + return $this->xpath; + } + + public function set_domDocument($domDocument) + { + $this->domDocument = $domDocument; + return $this; + } + + /** + * @brief Build an XMLInvoice_Reader object from an XML file + * @param $filename (string) file and path to the file + * @return \Noalyss\XMLDocument\XMLInvoice_Reader + * @throws \Exception if xml not valid + */ + static function build_from_file($filename) + { + if (!file_exists($filename)) + { + throw new \Exception("XR101: file not found $filename", 101); + } + $dm = new \DOMDocument(); + if ($dm->load($filename) == false) + { + throw new \Exception("XR106: cannot load file", 106); + } + if ( $dm->getElementsByTagName("CreditNote")->length == 1) + { + return new XMLCreditNote_Reader($dm); + } + if ( $dm->getElementsByTagName("Invoice")->length == 1) + { + return new XMLInvoice_Reader($dm); + } + throw new \Exception("XR116: unknown XML", 116); + } + + /** + * @brief Build an XMLInvoice_Reader object from an XML string + * @param $string (string) XML + * @return \Noalyss\XMLDocument\XMLInvoice_Reader + * @throws \Exception if xml not valid + */ + static function build_from_string($string) + { + $dm = new \DOMDocument(); + if ($dm->loadXML($string) == false) + { + throw new \Exception("XR130: cannot load XML", 130); + } + if ( $dm->getElementsByTagName("CreditNote")->length == 1) + { + return new XMLCreditNote_Reader($dm); + } + if ( $dm->getElementsByTagName("Invoice")->length == 1) + { + return new XMLInvoice_Reader($dm); + } + throw new \Exception("XR120: unknown XML", 120); + } + + + + /** + * @brief returns the embedded document in an array (keys : filecontent (BYTES),mimecode , filename) + * or false if there is no document + * @return bool|array of Document_Reference + * @throws \Exception if there are several documents + * + */ + public function get_embedded_document() + { + $a_document_reference = array(); + foreach (array( + "AdditionalDocumentReference", + "ReceiptDocumentReference", + "StatementDocumentReference", + "OriginatorDocumentReference", + "ContractDocumentReference" + ) + as $document) + { + $document = $this->domDocument->getElementsByTagName($document); + if ($document->length == 0) + { + continue; + } + for ($e = 0; $e < $document->count(); $e++) + { + $item = $document->item($e); + + if ($item->nodeType == XML_ELEMENT_NODE) + { + $id = $item->getElementsByTagName("ID")[0]?->nodeValue; + $description = $item->getElementsByTagName("DocumentDescription")[0]?->nodeValue; + $embedded_document = $item->getElementsByTagName("EmbeddedDocumentBinaryObject"); + if ($embedded_document->length == 0) + { + continue; + } + $binary_object = new Binary_Object; + $binary_object->filecontent = base64_decode($embedded_document[0]->nodeValue); + $binary_object->mimecode = $embedded_document[0]->getAttribute("mimeCode"); + $binary_object->filename = $embedded_document[0]->getAttribute("filename"); + $document_reference = new Document_Reference(); + $document_reference->setId($id) + ->setDescription($description) + ->setBinary_object($binary_object); + $a_document_reference[] = clone $document_reference; + } + } + } + return $a_document_reference; + } + /** + * @brief execute a XPATH query of the DOMDocument and return the result + * or null if nothing found + * @param $query (string) valid XPath Query + * @return null or DOMNodeList or DOMElement + */ + public function get_node($query) + { + + $this->registerNS(); + if ($this->xpath->query($query)->length == 0) + { + return null; + } + return $this->xpath->query($query); + } + /** + * @brief get the node value + * @param $query (string) valid XPath query + * @param $ix (int) the item number + * @return string + */ + function get_node_value($query, $ix = 0) + { + return $this->get_node($query)?->item($ix)?->nodeValue; + } + + /** + * @brief get the customer info from XML + * @return array + */ + function get_customer(): array + { + $result = []; + $result['ID'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cbc:EndpointID[1]"); + $result['name'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]'); + $result['street'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]'); + $result['city'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]'); + $result['postcode'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]'); + $result['country_code'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]"); + $result['company_id'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]"); + $result['scheme'] = $this->get_node("//cac:AccountingCustomerParty[1]/cac:Party[1]/cbc:EndpointID[1]")[0]->getAttribute("schemeID"); + return $result; + } + + /** + * @brief get the supplier info from XML + * @return array + */ + function get_supplier(): array + { + $result = []; + $result['ID'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cbc:EndpointID[1]"); + $result['name'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]"); + $result['street'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]"); + $result['city'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]"); + $result['postcode'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]"); + $result['country_code'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]"); + $result['company_id'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]"); + $result['scheme'] = $this->get_node("//cac:AccountingSupplierParty[1]/cac:Party[1]/cbc:EndpointID[1]")[0]->getAttribute("schemeID"); + return $result; + } + + + + /** + * @brief get the Payment Means info from XML + * @return array + */ + function get_payment_mean(): array + { + $result = []; + $result['payment_code'] = $this->get_node_value("//cac:PaymentMeans[1]/cbc:PaymentMeansCode[1]"); + $result['label'] = $this->get_node_value("//cac:PaymentMeans[1]/cbc:PaymentID[1]"); + $result['iban'] = $this->get_node_value("//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cbc:ID[1]"); + $result['bic'] = $this->get_node_value("//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cac:FinancialInstitutionBranch[1]/cbc:ID[1]"); + $result['note'] = []; + $note = $this->get_node("//cac:PaymentTerms/cbc:Note"); + if ($note != null) + { + $a = $note->length; + for ($i = 0; $i < $a; $i++) + { + $result['note'][] = $note->item(0)->nodeValue; + } + } + /** + + In geval van betaling binnen 14 dagen is 2% (52.00€) betalingskorting van + toepassing en het te betalen bedrag = 3053.68€ + En cas de paiement dans les 14 jours, l'escompte conditionnel de 2% (52.00€) est appliqué et le montant payable = 3053.68€ + In case of payment within 14 days, 2% (52.00€) conditional cash/payment discount applies and the payable amount = 3053.68€ + + + */ + return $result; + } + + /** + * @brief get the node value from simpleXML + * @param $xml (\SimpleXMLElement) fragment of XML dom + * @param $query (string) XPath query + * @return string + */ + protected function get_simple_xml_value(\SimpleXMLElement $xml, $query): string + { + $this->registerNS($xml); + + $x = $xml->xpath($query); + $result = (count($x) == 0) ? "" : $x[0]; + return (string) $result; + } + + /** + * @brief get the amount summary info from XML + * @return array + */ + function get_amount_summary(): array + { + $result = []; + $node = $this->get_node("//cac:LegalMonetaryTotal"); + $xml = simplexml_import_dom($node->item(0)); + $result['LineExtensionAmount'] = $this->get_simple_xml_value($xml, "cbc:LineExtensionAmount"); + $result['TaxExclusiveAmount'] = $this->get_simple_xml_value($xml, "cbc:TaxExclusiveAmount"); + $result['TaxInclusiveAmount'] = $this->get_simple_xml_value($xml, "cbc:TaxInclusiveAmount"); + $result['PayableAmount'] = $this->get_simple_xml_value($xml, "cbc:PayableAmount"); + $result['AllowanceTotalAmount'] = $this->get_simple_xml_value($xml, "cbc:AllowanceTotalAmount"); + $result['AllowanceTotalAmount'] = ($result['AllowanceTotalAmount'] == "") ? 0 : $result['AllowanceTotalAmount']; + $result['ChargeTotalAmount'] = $this->get_simple_xml_value($xml, "cbc:ChargeTotalAmount"); + $result['ChargeTotalAmount'] = ($result['ChargeTotalAmount'] == "") ? 0 : $result['ChargeTotalAmount']; + return $result; + } + + /** + * @brief get the customer info from XML + * @return array + */ + + /** + * + @code + + false + 64 + Conditional cash/payment discount | Korting contant | Escompte Conditionnel 2% + 4.00 + + S + 6.00 + + VAT + + + + @encode + */ + function get_allowance(): array + { + $result = []; + return $result; + } + /** + * @brief return the code of the document (cbc:"document"TypeCode) + * @return string "document string + cbc:"document"TypeCode" + */ + abstract function get_document_type_code(); + /** + * + * @return array + * @TODODNY + * Implémenter les allowances + */ + function get_info(): array + { + $result = []; + $result['id'] = $this->get_node_value('cbc:ID'); + $result['IssueDate'] = $this->get_node_value('cbc:IssueDate'); + $result['DueDate'] = $this->get_node_value('cbc:DueDate'); + $result['InvoiceTypeCode'] =$this->get_document_type_code(); + $result['DocumentCurrencyCode'] = $this->get_node_value('cbc:DocumentCurrencyCode'); + $result['BuyerReference'] = $this->get_node_value('cbc:BuyerReference'); + $result['ActualDeliveryDate'] = $this->get_node_value('//cac:Delivery[1]/cbc:ActualDeliveryDate[1]'); + /* + + 2018-07-01 + + */ + return $result; + } + + /** + * @brief make a PDF with the information from XMLInvoice + * @param \Database $cn + * @returns \PDF + */ + public function to_pdf(\Database $cn): \PDF + { + $pdf = new \PDF($cn); + $result = $this->get_info(); + + $pdf->setDossierInfo(_(" id ") . " " . $result['id']); + $pdf->AliasNbPages(); + $pdf->setAuthor("Noalyss"); + $pdf->AddPage(); + // 180 mm large + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Information facture")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $pdf->write(4, sprintf(_("Document ID %s"), $result['id'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Date facture %s"), $result['IssueDate'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Date échéance %s"), $result['DueDate'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Type et code document %s"), $result['InvoiceTypeCode'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Devise document %s"), $result['DocumentCurrencyCode'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Référence client %s"), $result['BuyerReference'])); + $pdf->ln(); + $pdf->write(4, sprintf(_("Date Livraison %s"), $result['ActualDeliveryDate'])); + $pdf->ln(10); + + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Fournisseur")); + $pdf->line_new(12); + $supplier = $this->get_supplier(); + $pdf->setFont("DejaVu", "", 7); + $pdf->write_cell(60, 4, $supplier['name']); + $pdf->write_cell(60, 4, $supplier['company_id']); + $pdf->write_cell(60, 4, $supplier['ID']); + $pdf->line_new(); + $pdf->write_cell(60, 4, $supplier['street']); + $pdf->write_cell(30, 4, $supplier['postcode']); + $pdf->write_cell(60, 4, $supplier['city']); + $pdf->write_cell(20, 4, $supplier['country_code']); + $pdf->line_new(10); + + $customer = $this->get_customer(); + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Client")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $pdf->write_cell(60, 4, $customer['name']); + $pdf->write_cell(60, 4, $customer['company_id']); + $pdf->write_cell(60, 4, $customer['ID']); + $pdf->line_new(); + $pdf->write_cell(60, 4, $customer['street']); + $pdf->write_cell(40, 4, $customer['postcode']); + $pdf->write_cell(60, 4, $customer['city']); + $pdf->write_cell(20, 4, $customer['country_code']); + $pdf->line_new(10); + + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Articles")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $result = $this->get_invoiceLine(); + $pdf->write_cell(50, 4, _("Code"), border: 'B'); + $pdf->write_cell(50, 4, _("Description"), border: 'B'); + $pdf->write_cell(30, 4, _("TVA"), border: 'B', align: 'R'); + $pdf->write_cell(25, 4, _("Quantité"), border: 'B', align: 'R'); + $pdf->write_cell(25, 4, _("Montant HT"), border: 'B', align: 'R'); + $pdf->line_new(); + + $nb_inline = count($result); + for ($i = 0; $i < $nb_inline; $i++) + { + $pdf->write_cell(50, 4, $result[$i]['name']); + $pdf->write_cell(50, 4, $result[$i]['description']); + $pdf->write_cell(25, 4, $result[$i]['tva_percent'], align: 'R'); + $pdf->write_cell(5, 4, $result[$i]['tva_id']); + $pdf->write_cell(25, 4, $result[$i]['quantity'], align: 'R'); + $pdf->write_cell(25, 4, $result[$i]['amount'], align: 'R'); + $pdf->line_new(); + } + $pdf->line_new(10); + + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Totaux")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $result = $this->get_amount_summary(); +// @TODO DNY : Qu'est-ce que LineExtension Amount ?? + $pdf->write_cell(50, 4, _("Base taxe")); + $pdf->write_cell(50, 4, $result['LineExtensionAmount']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Total Hors Taxe")); + $pdf->write_cell(50, 4, $result['TaxExclusiveAmount']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Total avec Taxe")); + $pdf->write_cell(50, 4, $result['TaxInclusiveAmount']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Total à payer")); + $pdf->write_cell(50, 4, $result['PayableAmount']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Total réduction")); + $pdf->write_cell(50, 4, $result['AllowanceTotalAmount']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Total charge")); + $pdf->write_cell(50, 4, $result['ChargeTotalAmount']); + $pdf->line_new(); + + $pdf->line_new(10); + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("TVA")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $result = $this->get_taxes(); + $pdf->write_cell(25, 4, _("% Taxe"), align: 'R', border: 'B'); + $pdf->write_cell(5, 4, _("Code taxe"), border: 'B'); + $pdf->write_cell(50, 4, _("Base"), align: 'R', border: 'B'); + $pdf->write_cell(50, 4, _("Taxe"), align: 'R', border: 'B'); + $pdf->line_new(); + $nb_inline = count($result); + for ($i = 0; $i < $nb_inline; $i++) + { + $pdf->write_cell(25, 4, $result[$i]['tax_percent'], align: 'R'); + $pdf->write_cell(5, 4, $result[$i]['tax_id']); + $pdf->write_cell(50, 4, $result[$i]['taxable_amount'], align: 'R'); + $pdf->write_cell(50, 4, $result[$i]['tax'], align: 'R'); + + $pdf->line_new(); + } + $pdf->line_new(10); + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(60, 4, _("Paiement")); + $pdf->line_new(10); + $pdf->setFont("DejaVu", "", 7); + $result = $this->get_payment_mean(); + $pdf->write_cell(50, 4, _("Code")); + $pdf->write_cell(50, 4, $result['payment_code']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("IBAN")); + $pdf->write_cell(50, 4, $result['iban']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("BIC")); + $pdf->write_cell(50, 4, $result['bic']); + $pdf->line_new(); + $pdf->write_cell(50, 4, _("Communication")); + $pdf->write_cell(50, 4, $result['label']); + $pdf->line_new(); + $nb_note = count($result['note']); + for ($i = 0; $i < $nb_note; $i++) + { + $pdf->write_cell(40, 4, _("note") . " " . $i); + $pdf->write_multi(140, 4, str_replace(["\n", "\r", "\t"], " ", $result['note'][$i])); + $pdf->line_new(); + } + /** + * display name of embedded from files + * @var $result(array of Document_Reference) + */ + $result=$this->get_embedded_document(); + if ( count($result) > 0) + { + $pdf->setFont("DejaVu", "B", 12); + $pdf->write_cell(50,4,_('Documents')); + $pdf->line_new(); + $pdf->setFont("DejaVu", "", 7); + $nb_result=count($result); + for ($i=0;$i< $nb_result;$i++) + { + $binary=$result[$i]->getBinary_object(); + $pdf->write_cell(50,4,$result[$i]->getId()); + $pdf->write_cell(50,4,$binary->filename); + $pdf->write_cell(50,4,$result[$i]->getDescription()); + $pdf->line_new(); + + } + + } + return $pdf; + } +} diff --git a/include/XMLDocument/xmlcreditnote.class.php b/include/XMLDocument/xmlcreditnote.class.php new file mode 100644 index 000000000..0ec62cdb1 --- /dev/null +++ b/include/XMLDocument/xmlcreditnote.class.php @@ -0,0 +1,31 @@ + string 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' + 'ns2' => string 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2' + 'cac' => string 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' + 'ns4' => string 'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2' + ) + * + */ +class XMLCreditNote_Reader extends XML_Reader +{ + + public function __construct(\DOMDocument $domDocument) + { + parent::__construct($domDocument); + } + + /** + * @brief Build an XMLInvoice_Reader object from an XML string + * @param $string (string) XML + * @return \Noalyss\XMLDocument\XMLInvoice_Reader + * @throws \Exception if xml not valid + */ + static function build_from_string($string) + { + $dm = new \DOMDocument(); + if ($dm->loadXML($string) != false) + { + return new XMLCreditNote_Reader($dm); + } else + { + throw new \Exception("XC55: not a valid XML", 55); + } + } + + /** + * @brief Build an XMLInvoice_Reader object from an XML file + * @param $filename (string) file and path to the file + * @return \Noalyss\XMLDocument\XMLInvoice_Reader + * @throws \Exception if xml not valid + */ + static function build_from_file($filename) + { + if (!file_exists($filename)) + { + throw new \Exception("XC62: file not found $filename", 62); + } + $dm = new \DOMDocument(); + if ($dm->load($filename) != false) + { + return new XMLCreditNote_Reader($dm); + } else + { + throw new \Exception("XC55: not a valid XML", 55); + } + } + + /** + * @brief retrieve InvoiceLines + @code + + 2 + -3 + -1500 + + 123 + + + Description 2 + item name 2 + + 21382183120983 + + + NO + + + 09348023 + + + S + 25.0 + + VAT + + + + + 500 + + + @endcode + */ + function get_invoiceLine(): array + { + $result = []; + $node = $this->get_node("//cac:CreditNoteLine"); + for ($e = 0; $e < $node->length; $e++) + { + $row = []; + $xml = simplexml_import_dom($node->item($e)); + $row ['quantity'] = $this->get_node_value("//cbc:CreditedQuantity", $e); + $row ['amount'] = $this->get_node_value("//cbc:LineExtensionAmount", $e); + $row ['description'] = $this->get_node_value("//cac:Item/cbc:Description", $e); + $row ['name'] = $this->get_node_value("//cac:CreditNoteLine/cac:Item/cbc:Name", $e); + $row ['unit_price'] = $this->get_node_value("//cac:CreditNoteLine/cac:Price/cbc:PriceAmount", $e); + $row ['tva_id'] = $this->get_node_value("//cac:CreditNoteLine/cac:Item/cac:ClassifiedTaxCategory/cbc:ID", $e); + $row ['tva_percent'] = $this->get_node_value("//cac:CreditNoteLine/cac:Item/cac:ClassifiedTaxCategory/cbc:Percent", $e); + + $result[] = $row; + } + return $result; + } + /** + * @brief return the code of the document + * @return string credit_node + code + */ + + function get_document_type_code() + { + return "credit note ".$this->get_node_value('cbc:CreditNoteTypeCode'); + } + /** + * @brief before executing xpath->query the namespace must be registered + * the NS are different for each type of doc + */ + + public function get_namespace() + { + + $a_namespace=array( + "cac"=> 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' + ,"cbc"=> 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' + ,"ns4"=>'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2' + ,"ns2"=>'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2' + ); + return $a_namespace; + } + /** + * @brief get the Taxes info from XML + * @return array + */ + function get_taxes(): array + { + $result = []; + $node = $this->get_node("//cac:TaxTotal/cac:TaxSubtotal"); + + for ($e = 0; $e < $node->length; $e++) + { + $row = []; + $xml = simplexml_import_dom($node->item($e)); + // /Invoice/cac:TaxTotal[1]/cac:TaxSubtotal[1]/cbc:TaxableAmount[1] + $this->registerNS($xml); + + $row ['taxable_amount'] = $xml->xpath("//cbc:TaxableAmount")[$e] . ""; + $row ['tax'] = $xml->xpath("//cbc:TaxAmount")[$e] . ""; + $row ['tax_id'] = $xml->xpath("//cac:TaxCategory/cbc:ID")[$e] . ""; + $row ['tax_percent'] = $xml->xpath("//cac:TaxCategory/cbc:Percent")[$e] . ""; + if (isset($xml->xpath("//cac:CreditNoteLine/cac:Item/cbc:Name")[$e])) + $row ['name'] =$xml->xpath("//cac:CreditNoteLine/cac:Item/cbc:Name")[$e].""; + else + $row['name']=""; + /** + * @TODODNY + * Implémenter les allowances + */ + $result[] = $row; + } + return $result; + } + +} diff --git a/include/XMLDocument/xmlinvoice.class.php b/include/XMLDocument/xmlinvoice.class.php index 47fb983e2..e99032610 100644 --- a/include/XMLDocument/xmlinvoice.class.php +++ b/include/XMLDocument/xmlinvoice.class.php @@ -278,7 +278,9 @@ abstract class XMLInvoice extends \DOMDocument $VAT_SubTotal[$idx_subtotal]['idx']=$idx; $VAT_SubTotal[$idx_subtotal]['vat_code']=$result['operation'][$i]['vat_code'] ; $VAT_SubTotal[$idx_subtotal]['percent']=$percent; + $VAT_SubTotal[$idx_subtotal]['vatex']=$acc_tva->vx_code; $VAT_SubTotal[$idx_subtotal]['amount']=$VAT_SubTotal[$idx_subtotal]['vat']=0; + $idx_subtotal++; } /** @@ -371,6 +373,23 @@ abstract class XMLInvoice extends \DOMDocument ,$tva->tva_code ); } + elseif (! in_array($this->data['operation'][$i]['vat_code'],array("S","Z"))) + { + $card=new \Fiche( + $this->cn + ,$this->data['operation'][$i]['card_id'] + ); + $tva= \Acc_Tva::build($this->cn, $this->data['operation'][$i]['vat_id']); + if ( $tva->vx_code == "") + { + $a_error[]=sprintf(_("%s : %s code Exemption pour PEPPOL non configuré code TVA [ %s %s ]") + , $i + , $card->get_quick_code() + ,$tva->tva_id + ,$tva->tva_code + ); + } + } } return $a_error; } @@ -452,8 +471,9 @@ abstract class XMLInvoice extends \DOMDocument { $result['country']=substr($result['customer_vat_id'],0,2); } - // $result['endpoint_id']=$customer->get_attribute(ATTR_DEF_PEPPOLID,0); - $result['endpoint_id']= $result['customer_vat_id']; + $result['endpoint_id']=$customer->get_attribute(ATTR_DEF_PEPPOLID,0); + + return $result; } /** diff --git a/include/XMLDocument/xmlinvoice_reader.class.php b/include/XMLDocument/xmlinvoice_reader.class.php index 7d723841e..fd1d346bb 100644 --- a/include/XMLDocument/xmlinvoice_reader.class.php +++ b/include/XMLDocument/xmlinvoice_reader.class.php @@ -29,7 +29,7 @@ namespace Noalyss\XMLDocument; */ /** - * @file + * @class * @brief Get information from an XML * Exception code : * - 55 : XML Invalid @@ -37,47 +37,23 @@ namespace Noalyss\XMLDocument; * Namespace standard (from XSD) * * Array -( - [xml] => http://www.w3.org/XML/1998/namespace - [cbc] => urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2 - [cac] => urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 - [xmlns] => urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 -) + ( + [xml] => http://www.w3.org/XML/1998/namespace + [cbc] => urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2 + [cac] => urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 + [xmlns] => urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 + ) * */ -class XMLInvoice_Reader +class XMLInvoice_Reader extends XML_Reader { - protected \DOMDocument $domDocument; - protected readonly \DOMXPath $xpath; - public function __construct(\DOMDocument $domDocument) { - $this->domDocument = $domDocument; - $this->xpath = new \DOMXPath($this->domDocument); + parent::__construct($domDocument); + } - - /** - * - * @return \DOMDocument - */ - public function get_domDocument(): \DOMDocument - { - return $this->domDocument; - } - - public function get_xpath(): \DOMXPath - { - return $this->xpath; - } - - public function set_domDocument($domDocument) - { - $this->domDocument = $domDocument; - return $this; - } - /** * @brief Build an XMLInvoice_Reader object from an XML string * @param $string (string) XML @@ -95,8 +71,7 @@ class XMLInvoice_Reader throw new \Exception("XR55: not a valid XML",55); } } - - /** + /** * @brief Build an XMLInvoice_Reader object from an XML file * @param $filename (string) file and path to the file * @return \Noalyss\XMLDocument\XMLInvoice_Reader @@ -117,130 +92,6 @@ class XMLInvoice_Reader throw new \Exception("XR55: not a valid XML", 55); } } - - /** - * @brief execute a XPATH query of the DOMDocument and return the result - * or null if nothing found - * @param $query (string) valid XPath Query - * @return null or DOMNodeList or DOMElement - */ - public function get_node($query) - { - if ($this->xpath->query($query)->length == 0) - { - return null; - } - return $this->xpath->query($query); - } - - /** - * @brief returns the embedded document in an array (keys : filecontent (BYTES),mimecode , filename) - * or false if there is no document - * @return bool|array keys : filecontent (BYTES),mimecode , filename) - * or false if there is no document - * @throws \Exception if there are several documents - * - */ - public function get_embedded_document() - { - if (($node = $this->get_node("//cac:AdditionalDocumentReference")) == false) - { - return false; - } - if ($node->length > 1) - { - throw new \Exception("XR110 Too many documents found", 110); - } - ///@var DOMNodeList $data //cac:AdditionalDocumentReference[1]/cac:Attachment[1]/cbc:EmbeddedDocumentBinaryObject[1] - if ( - ($data = $this->get_node("//cac:AdditionalDocumentReference[1]/cac:Attachment[1]/cbc:EmbeddedDocumentBinaryObject[1]")) == null - ) - { - - throw new \Exception("X116 Document corrupted", 116); - } - $filecontent = base64_decode($data->item(0)->nodeValue); - $mimecode = $data->item(0)->getAttribute("mimeCode"); - $filename = $data->item(0)->getAttribute("filename"); - return array("filecontent" => $filecontent, - "mimecode" => $mimecode, - "filename" => $filename); - } - - /** - * @brief get the node value - * @param $query (string) valid XPath query - * @param $ix (int) the item number - * @return string - */ - function get_node_value($query, $ix = 0) - { - return $this->get_node($query)?->item($ix)?->nodeValue; - } - - /** - * @brief get the customer info from XML - * @return array - */ - function get_customer(): array - { - $result = []; - $result['ID'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cbc:EndpointID[1]"); - $result['name'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]'); - $result['street'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]'); - $result['city'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]'); - $result['postcode'] = $this->get_node_value('//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]'); - $result['country_code'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]"); - $result['company_id'] = $this->get_node_value("//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]"); - return $result; - } - - /** - * @brief get the supplier info from XML - * @return array - */ - function get_supplier(): array - { - $result = []; - $result['ID'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cbc:EndpointID[1]"); - $result['name'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]"); - $result['street'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]"); - $result['city'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]"); - $result['postcode'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]"); - $result['country_code'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]"); - $result['company_id'] = $this->get_node_value("//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]"); - return $result; - } - - /** - * @brief get the Taxes info from XML - * @return array - */ - function get_taxes(): array - { - $result = []; - $node = $this->get_node("//cac:TaxTotal/cac:TaxSubtotal"); - - for ($e = 0; $e < $node->length; $e++) - { - $row = []; - $xml = simplexml_import_dom($node->item($e)); - // /Invoice/cac:TaxTotal[1]/cac:TaxSubtotal[1]/cbc:TaxableAmount[1] - - $row ['taxable_amount'] = $xml->xpath("//cbc:TaxableAmount")[$e] . ""; - $row ['tax'] = $xml->xpath("//cbc:TaxAmount")[$e] . ""; - $row ['tax_id'] = $xml->xpath("//cac:TaxCategory/cbc:ID")[$e] . ""; - $row ['tax_percent'] = $xml->xpath("//cac:TaxCategory/cbc:Percent")[$e] . ""; - // $row ['name'] =$xml->xpath("//cac:InvoiceLine/cac:Item/cbc:Name")[$e]."
"; - /** - * @TODODNY - * Implémenter les allowances - */ - $result[] = $row; - } - return $result; - } - /** * @brief retrieve InvoiceLines * @TODO XMLInvoice_Reader->get_invoiceLine * Implémenter les allowances @@ -265,286 +116,62 @@ class XMLInvoice_Reader } return $result; } - /** - * @brief get the Payment Means info from XML - * @return array + * @brief return the code of the document + * @return string invoice + code */ - function get_payment_mean(): array + function get_document_type_code() { - $result = []; - $result['payment_code'] = $this->get_node_value("//cac:PaymentMeans[1]/cbc:PaymentMeansCode[1]"); - $result['label'] = $this->get_node_value("//cac:PaymentMeans[1]/cbc:PaymentID[1]"); - $result['iban'] = $this->get_node_value("//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cbc:ID[1]"); - $result['bic'] = $this->get_node_value("//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cac:FinancialInstitutionBranch[1]/cbc:ID[1]"); - $result['note'] = []; - $note = $this->get_node("//cac:PaymentTerms/cbc:Note"); - if ($note != null) - { - $a = $note->length; - for ($i = 0; $i < $a; $i++) - { - $result['note'][] = $note->item(0)->nodeValue; - } - } - /** - - In geval van betaling binnen 14 dagen is 2% (52.00€) betalingskorting van - toepassing en het te betalen bedrag = 3053.68€ - En cas de paiement dans les 14 jours, l'escompte conditionnel de 2% (52.00€) est appliqué et le montant payable = 3053.68€ - In case of payment within 14 days, 2% (52.00€) conditional cash/payment discount applies and the payable amount = 3053.68€ - - - */ - return $result; + return "invoice ".$this->get_node_value('cbc:InvoiceTypeCode'); } - /** - * @brief get the node value from simpleXML - * @param $xml (\SimpleXMLElement) fragment of XML dom - * @param $query (string) XPath query - * @return string + * @brief before executing xpath->query the namespace must be registered + * the NS are different for each type of doc + * @param $xml (null or simpleXML) */ - protected function get_simple_xml_value(\SimpleXMLElement $xml, $query): string + + public function get_namespace() { - $x = $xml->xpath($query); - $result = (count($x) == 0) ? "" : $x[0]; - return (string) $result; - } - - /** - * @brief get the amount summary info from XML - * @return array - */ - function get_amount_summary(): array - { - $result = []; - $node = $this->get_node("//cac:LegalMonetaryTotal"); - $xml = simplexml_import_dom($node->item(0)); - $result['LineExtensionAmount'] = $this->get_simple_xml_value($xml, "cbc:LineExtensionAmount"); - $result['TaxExclusiveAmount'] = $this->get_simple_xml_value($xml, "cbc:TaxExclusiveAmount"); - $result['TaxInclusiveAmount'] = $this->get_simple_xml_value($xml, "cbc:TaxInclusiveAmount"); - $result['PayableAmount'] = $this->get_simple_xml_value($xml, "cbc:PayableAmount"); - $result['AllowanceTotalAmount'] = $this->get_simple_xml_value($xml, "cbc:AllowanceTotalAmount"); - $result['AllowanceTotalAmount'] = ($result['AllowanceTotalAmount'] == "") ? 0 : $result['AllowanceTotalAmount']; - $result['ChargeTotalAmount'] = $this->get_simple_xml_value($xml, "cbc:ChargeTotalAmount"); - $result['ChargeTotalAmount'] = ($result['ChargeTotalAmount'] == "") ? 0 : $result['ChargeTotalAmount']; - return $result; - } - - /** - * @brief get the customer info from XML - * @return array - */ - - /** - * - @code - - false - 64 - Conditional cash/payment discount | Korting contant | Escompte Conditionnel 2% - 4.00 - - S - 6.00 - - VAT - - - - @encode - */ - function get_allowance(): array - { - $result = []; - return $result; - } - - /** - * - * @return array - * @TODODNY - * Implémenter les allowances - */ - function get_info(): array - { - $result = []; - $result['id'] = $this->get_node_value('cbc:ID'); - $result['IssueDate'] = $this->get_node_value('cbc:IssueDate'); - $result['DueDate'] = $this->get_node_value('cbc:DueDate'); - $result['InvoiceTypeCode'] = $this->get_node_value('cbc:InvoiceTypeCode'); - $result['DocumentCurrencyCode'] = $this->get_node_value('cbc:DocumentCurrencyCode'); - $result['BuyerReference'] = $this->get_node_value('cbc:BuyerReference'); - $result['ActualDeliveryDate'] = $this->get_node_value('//cac:Delivery[1]/cbc:ActualDeliveryDate[1]'); - /* - - 2018-07-01 - - */ - return $result; - } - - /** - * @brief make a PDF with the information from XMLInvoice - * @param \Database $cn - * @returns \PDF - */ - public function to_pdf(\Database $cn): \PDF - { - $pdf = new \PDF($cn); - $result = $this->get_info(); + $a_namespace=array( + "cac"=>'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' + ,"cbc"=>'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' + ,"ns4"=>'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2' + ); + return $a_namespace; - $pdf->setDossierInfo(_(" id ")." ".$result['id']); - $pdf->AliasNbPages(); - $pdf->setAuthor("Noalyss"); - $pdf->AddPage(); - // 180 mm large - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Information facture")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $pdf->write(4, sprintf(_("Document ID %s"), $result['id'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Date facture %s"), $result['IssueDate'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Date échéance %s"), $result['DueDate'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Code facture %s"), $result['InvoiceTypeCode'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Devise docuemnt %s"), $result['DocumentCurrencyCode'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Référence client %s"), $result['BuyerReference'])); - $pdf->ln(); - $pdf->write(4, sprintf(_("Date Livraison %s"), $result['ActualDeliveryDate'])); - $pdf->ln(10); + } + /** + * @brief get the Taxes info from XML + * @return array + */ + function get_taxes(): array + { + $result = []; + $node = $this->get_node("//cac:TaxTotal/cac:TaxSubtotal"); - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Fournisseur")); - $pdf->line_new(12); - $supplier = $this->get_supplier(); - $pdf->setFont("DejaVu", "", 7); - $pdf->write_cell(60, 4, $supplier['name']); - $pdf->write_cell(60, 4, $supplier['company_id']); - $pdf->write_cell(60, 4, $supplier['ID']); - $pdf->line_new(); - $pdf->write_cell(60, 4, $supplier['street']); - $pdf->write_cell(30, 4, $supplier['postcode']); - $pdf->write_cell(60, 4, $supplier['city']); - $pdf->write_cell(20, 4, $supplier['country_code']); - $pdf->line_new(10); - - $customer = $this->get_customer(); - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Client")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $pdf->write_cell(60, 4, $customer['name']); - $pdf->write_cell(60, 4, $customer['company_id']); - $pdf->write_cell(60, 4, $customer['ID']); - $pdf->line_new(); - $pdf->write_cell(60, 4, $customer['street']); - $pdf->write_cell(40, 4, $customer['postcode']); - $pdf->write_cell(60, 4, $customer['city']); - $pdf->write_cell(20, 4, $customer['country_code']); - $pdf->line_new(10); - - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Articles")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $result = $this->get_invoiceLine(); - $pdf->write_cell(50, 4, _("Code"), border: 'B'); - $pdf->write_cell(50, 4, _("Description"), border: 'B'); - $pdf->write_cell(30, 4, _("TVA"), border: 'B', align: 'R'); - $pdf->write_cell(25, 4, _("Quantité"), border: 'B', align: 'R'); - $pdf->write_cell(25, 4, _("Montant HT"), border: 'B', align: 'R'); - $pdf->line_new(); - - $nb_inline = count($result); - for ($i = 0; $i < $nb_inline; $i++) + for ($e = 0; $e < $node->length; $e++) { - $pdf->write_cell(50, 4, $result[$i]['name']); - $pdf->write_cell(50, 4, $result[$i]['description']); - $pdf->write_cell(25, 4, $result[$i]['tva_percent'], align: 'R'); - $pdf->write_cell(5, 4, $result[$i]['tva_id']); - $pdf->write_cell(25, 4, $result[$i]['quantity'], align: 'R'); - $pdf->write_cell(25, 4, $result[$i]['amount'], align: 'R'); - $pdf->line_new(); + $row = []; + $xml = simplexml_import_dom($node->item($e)); + // /Invoice/cac:TaxTotal[1]/cac:TaxSubtotal[1]/cbc:TaxableAmount[1] + $this->registerNS($xml); + + $row ['taxable_amount'] = $xml->xpath("//cbc:TaxableAmount")[$e] . ""; + $row ['tax'] = $xml->xpath("//cbc:TaxAmount")[$e] . ""; + $row ['tax_id'] = $xml->xpath("//cac:TaxCategory/cbc:ID")[$e] . ""; + $row ['tax_percent'] = $xml->xpath("//cac:TaxCategory/cbc:Percent")[$e] . ""; + if (isset($xml->xpath("//cac:InvoiceLine/cac:Item/cbc:Name")[$e])) + { + $row ['name'] =$xml->xpath("//cac:InvoiceLine/cac:Item/cbc:Name")[$e].""; + }else { + $row ['name'] =""; + } + /** + * @TODODNY + * Implémenter les allowances + */ + $result[] = $row; } - $pdf->line_new(10); - - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Totaux")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $result = $this->get_amount_summary(); -// @TODO DNY : Qu'est-ce que LineExtension Amount ?? - $pdf->write_cell(50, 4, _("Base taxe")); - $pdf->write_cell(50, 4, $result['LineExtensionAmount']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Total Hors Taxe")); - $pdf->write_cell(50, 4, $result['TaxExclusiveAmount']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Total avec Taxe")); - $pdf->write_cell(50, 4, $result['TaxInclusiveAmount']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Total à payer")); - $pdf->write_cell(50, 4, $result['PayableAmount']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Total réduction")); - $pdf->write_cell(50, 4, $result['AllowanceTotalAmount']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Total charge")); - $pdf->write_cell(50, 4, $result['ChargeTotalAmount']); - $pdf->line_new(); - - $pdf->line_new(10); - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("TVA")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $result = $this->get_taxes(); - $pdf->write_cell(25, 4, _("% Taxe"), align: 'R', border: 'B'); - $pdf->write_cell(5, 4, _("Code taxe"), border: 'B'); - $pdf->write_cell(50, 4, _("Base"), align: 'R', border: 'B'); - $pdf->write_cell(50, 4, _("Taxe"), align: 'R', border: 'B'); - $pdf->line_new(); - $nb_inline = count($result); - for ($i = 0; $i < $nb_inline; $i++) - { - $pdf->write_cell(25, 4, $result[$i]['tax_percent'], align: 'R'); - $pdf->write_cell(5, 4, $result[$i]['tax_id']); - $pdf->write_cell(50, 4, $result[$i]['taxable_amount'], align: 'R'); - $pdf->write_cell(50, 4, $result[$i]['tax'], align: 'R'); - - $pdf->line_new(); - } - $pdf->line_new(10); - $pdf->setFont("DejaVu", "B", 12); - $pdf->write_cell(60, 4, _("Paiement")); - $pdf->line_new(10); - $pdf->setFont("DejaVu", "", 7); - $result = $this->get_payment_mean(); - $pdf->write_cell(50, 4, _("Code")); - $pdf->write_cell(50, 4, $result['payment_code']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("IBAN")); - $pdf->write_cell(50, 4, $result['iban']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("BIC")); - $pdf->write_cell(50, 4, $result['bic']); - $pdf->line_new(); - $pdf->write_cell(50, 4, _("Communication")); - $pdf->write_cell(50, 4, $result['label']); - $pdf->line_new(); - $nb_note = count($result['note']); - for ($i = 0; $i < $nb_note; $i++) - { - $pdf->write_cell(40, 4, _("note") . " " . $i); - $pdf->write_multi(140, 4, str_replace(["\n","\r","\t"]," ",$result['note'][$i])); - $pdf->line_new(); - } - return $pdf; + return $result; } } diff --git a/include/ajax/ajax_account.php b/include/ajax/ajax_account.php index 61d1688e6..4f0d1b4ba 100644 --- a/include/ajax/ajax_account.php +++ b/include/ajax/ajax_account.php @@ -50,7 +50,10 @@ switch ($op2) * ----------------------------------------------------------------------*/ case "sf": - $ipopup=$ctl; + if ( ! isset($ctl)) { + $ctl= uniqid(); + } + $ipopup=$ctl; $attr=sprintf('this.ctl=\'%s\';',$ipopup); $ctl.='_content'; $it=new IText('acc_query'); diff --git a/include/ajax/ajax_ledger.php b/include/ajax/ajax_ledger.php index 93549280e..fa2fae901 100644 --- a/include/ajax/ajax_ledger.php +++ b/include/ajax/ajax_ledger.php @@ -566,6 +566,100 @@ switch ($action) { $acc_operation_note= Acc_Operation_Note::build_jrn_id($jr_id); echo substr($acc_operation_note->getNote()??"",0,120); + return; + case "rmsup": + //------------------------------------------------ + // Remove a document from JRN_SUP_DOCUMENT + //------------------------------------------------ + $js_id=$http->post("js_id","number"); + $jrn_sup= new Jrn_Sup_Document_SQL($cn,$js_id); + $jrn_sup->delete(); + // no answer, we stop here + return; + case 'input_file': + //------------------------------------------------ + // Display form for adding file , directly HTML + // + //------------------------------------------------ + require_once NOALYSS_TEMPLATE."/ajax_ledger+input_file.php"; + return; + case 'save_file': + //------------------------------------------------ + // Add a document to the operation + //------------------------------------------------ + if (sizeof($_FILES)==0) { + return; + } + $nb=count($_FILES['document_supplemental']["name"]); + $cn->start(); + for ($i=0;$i<$nb;$i++) + { + $file= tempnam($_ENV["TMP"], "sup_file"); + if ( move_uploaded_file($_FILES['document_supplemental']['tmp_name'][$i],$file)) + { + if ( ($oid=$cn->lo_import($file)) != false ) + { + $jrn_sup=new Jrn_Sup_Document_SQL($cn); + $jrn_sup->jr_id=$jr_id; + $jrn_sup->js_lob=$oid; + $jrn_sup->js_mimetype=$_FILES['document_supplemental']['type'][$i]; + $jrn_sup->js_filename=$_FILES['document_supplemental']['name'][$i]; + $jrn_sup->insert(); + $rowid=sprintf("row_js_%s_%s",$div,$jrn_sup->js_id); + // @var $download (url) to send file + $download="export.php?". http_build_query( + [ + "act"=>"RAW:suppl-document" + ,"js_id"=>$jrn_sup->js_id + ,"gDossier"=>$gDossier + ]); + + + $script_remove="Supplement_Document.delete_document('$gDossier','$div','{$jrn_sup->js_id}','$jr_id')"; + $icon_remove=\Icon_Action::trash(uniqid("sdd"),$script_remove); + echo << + +
+ {$jrn_sup->js_description} +
+
+ {$icon_remove} +
+ +EOF; + } + else + { + // failed + print '
'; + echo_warning(_("1 Echec ").$_FILES["name"]); + print '
'; + } + + } + else + { + //failed + // failed + print '
'; + echo_warning(_("2 Echec ").$_FILES["name"]); + print '
'; + } + } + + $cn->commit(); + return; + case 'refresh_file': + //------------------------------------------------ + // refresh list of suppemental files + //------------------------------------------------ + Acc_Document::display_supplementary_doc($cn, $http->get("div"), $http->get("jr_id")); + return; } $html = escape_xml($html); diff --git a/include/ajax/ajax_search_peppol.php b/include/ajax/ajax_search_peppol.php index be5ad08b5..47fd92e9c 100644 --- a/include/ajax/ajax_search_peppol.php +++ b/include/ajax/ajax_search_peppol.php @@ -78,7 +78,11 @@ echo \HtmlInput::title_box(_("Recherche PEPPOL Directory"), 'peppol_id_search_di $input_query = new IText("query", $query); $select_filter = new ISelect("filter"); - $select_filter->transform(["vatid" => _("Numéro de TVA"), "entid" => _("Numéro entreprise"), "name" => _("Nom")]); + $select_filter->transform(["vatid" => _("Numéro de TVA") + , "entid" => _("Numéro entreprise") + , "peppolid" => _("Endpoint (PEPPOL ID)") + , "name" => _("Nom") + ]); $select_filter->selected = $filter ?> input() ?> @@ -97,7 +101,7 @@ echo \HtmlInput::title_box(_("Recherche PEPPOL Directory"), 'peppol_id_search_di '; // div class content return; @@ -127,6 +131,9 @@ switch ($filter) } $search = http_build_query(["participant" => 'iso6523-actorid-upis::0208:' . $query]); break; + case 'peppolid': + $search = http_build_query(["participant" => 'iso6523-actorid-upis::' . $query]); + break; default: throw new \Exception("ASP129 unknown filter",129); } diff --git a/include/ajax/ajax_search_vatex.php b/include/ajax/ajax_search_vatex.php new file mode 100644 index 000000000..ce8bdd38b --- /dev/null +++ b/include/ajax/ajax_search_vatex.php @@ -0,0 +1,61 @@ +get("select_code","string",""); + $dgbox=$http->get("dgbox"); + +} catch (Exception $exc) { + echo $exc->getTraceAsString(); +} + + +if ($select_code == "") +{ + + require_once NOALYSS_TEMPLATE."/ajax-search_vatex.php"; + return; +} + +//------------------------------------------------ +// a VATEX Code has been selected +//------------------------------------------------ +if ($select_code != "") +{ + $row=$cn->get_row("select vx_code,vx_code_name,vx_description,vx_remark from vatex_code where vx_code=$1", + [$select_code]); + $answer=array(); + if ( ! empty ($row)) + { + $answer['vx_code']=$row['vx_code']; + $answer['vx_value']=Icon_Action::trash(uniqid(),"vat_code.select_value('xx')").$row['vx_code']; + $answer['vx_description']=$row['vx_description'].span($row['vx_remark'],' class="text-muted" '); + }else { + $answer['vx_code']=$answer['vx_value']=$answer['vx_description']=""; + } + echo json_response($answer); + return; +} diff --git a/include/anc_od.inc.php b/include/anc_od.inc.php index c7bad6b60..e5892d216 100644 --- a/include/anc_od.inc.php +++ b/include/anc_od.inc.php @@ -41,27 +41,28 @@ if ( ! $m ) } $dossier_id=Dossier::id(); - - -echo ' -"; $html=ob_get_contents(); ob_end_clean(); diff --git a/include/lib/message_javascript.php b/include/lib/message_javascript.php index a6866c7bc..0e8ff660b 100644 --- a/include/lib/message_javascript.php +++ b/include/lib/message_javascript.php @@ -107,9 +107,9 @@ content[72]=""; content[74]=""; content[75]=""; -content[76]=""; +content[76]=""; content[77]=""; - + content[78]=""; content[79]=""; diff --git a/include/lib/pdf_core.class.php b/include/lib/pdf_core.class.php index 754ea5fdc..8392ccf62 100644 --- a/include/lib/pdf_core.class.php +++ b/include/lib/pdf_core.class.php @@ -64,7 +64,7 @@ class PDF_Core extends TFPDF - private $cells=array(); + protected $cells=array(); protected $bigger; public function __construct ( $orientation = 'P', $unit = 'mm', $format = 'A4') @@ -119,7 +119,7 @@ class PDF_Core extends TFPDF * @param $p_text String * @param $p_colSize size of the column in User Unit */ - private function count_nb_row($p_text,$p_colSize) + protected function count_nb_row($p_text,$p_colSize) { // If colSize is bigger than the size of the string then it takes 1 line if ( $this->GetStringWidth($p_text) <= $p_colSize) return 1; @@ -153,7 +153,7 @@ class PDF_Core extends TFPDF * Check if a page must be added due a MultiCell * @return boolean */ - private function check_page_add() + protected function check_page_add() { // break on page $size=count($this->cells); @@ -260,7 +260,7 @@ class PDF_Core extends TFPDF } $this->cells=array(); } - private function add_cell(Cellule $Ce) + protected function add_cell(Cellule $Ce) { $size=count($this->cells); $this->cells[$size]=$Ce; diff --git a/include/lib/select_box.class.php b/include/lib/select_box.class.php index 8c6cb4817..38d1395de 100644 --- a/include/lib/select_box.class.php +++ b/include/lib/select_box.class.php @@ -156,17 +156,17 @@ class Select_Box { if ($this->item[$i]['type']=="url") { - printf('
  • %s
  • ', $this->item[$i]['url'], $this->item[$i]['label']); + printf('
  • %s
  • ', $this->item[$i]['url'], $this->item[$i]['label']); } else // For javascript if ($this->item[$i]['type']=="javascript") { - printf('
  • %s
  • ', $this->item[$i]['javascript'], + printf('
  • %s
  • ', $this->item[$i]['javascript'], $this->item[$i]['label']); } else if ($this->item[$i]['type']=="value") { - printf('
  • %s
  • ', $this->item[$i]['javascript'], + printf('
  • %s
  • ', $this->item[$i]['javascript'], $this->item[$i]['label']); } else if ($this->item[$i]['type']=="input") diff --git a/include/lib/user_menu.php b/include/lib/user_menu.php index 4b189f892..5148f8666 100644 --- a/include/lib/user_menu.php +++ b/include/lib/user_menu.php @@ -101,7 +101,7 @@ function MenuAdmin() ); } - $menu=ShowItem($item,'H',"nav-item","nav-link",$def,'nav nav-pills nav-fill '); + $menu=show_menu_extension($item,$def); return $menu; } diff --git a/include/template/ajax-search_vatex.php b/include/template/ajax-search_vatex.php new file mode 100644 index 000000000..7c021ac55 --- /dev/null +++ b/include/template/ajax-search_vatex.php @@ -0,0 +1,97 @@ +get_array("select vx_code,vx_code_name,vx_description,vx_remark , vx_country from vatex_code order by 1"); +$nb_vatex_code = count($a_vatex_code); + + +//@var $os_country (ISELECT) filter table by country +$os_country=new \ISelect("filter_country"); +$os_country->transform(array( + "countryeu"=>"Europe", + ""=>_("Tous"), + "countryfr"=>"France" + ) + ); +$os_country->javascript=' onchange="vat_code.filter_country()" '; +?> +
    +input()?> + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    + + + + + + + + + + + + +
    +
      +
    • + +
    • +
    +
    \ No newline at end of file diff --git a/include/template/ajax_ledger+input_file.php b/include/template/ajax_ledger+input_file.php new file mode 100644 index 000000000..5bcd27a7a --- /dev/null +++ b/include/template/ajax_ledger+input_file.php @@ -0,0 +1,68 @@ + list of files to update after uploading + */ + +$dgbox=$http->request("dgbox"); +$form_id="save_file{$div}"; +$progress="progress{$div}"; +$max_post_size=convert_ini_unit(ini_get("post_max_size")); + +echo \HtmlInput::title_box(_("Ajout de fichier"), $dgbox); +?> +
    + + +

    + +

    +
    + + + + + + + + + +
    +
      +
    • + " onclick="return Supplement_Document.save_file('');"> +
    • +
    • + +
    • +
    +
    + +
    \ No newline at end of file diff --git a/include/template/ledger_detail_bottom.php b/include/template/ledger_detail_bottom.php index 8a5254541..c17f62822 100644 --- a/include/template/ledger_detail_bottom.php +++ b/include/template/ledger_detail_bottom.php @@ -45,6 +45,7 @@ $a_tab['linked_operation_div']=array('id'=>'linked_operation_div'.$div,'label'=> $a_tab['document_operation_div']=array('id'=>'document_operation_div'.$div,'label'=>_('Document').'('.$nb_document.')','display'=>'block'); $a_tab['linked_action_div']=array('id'=>'linked_action_div'.$div,'label'=>_('Actions Gestion').'('.count($a_followup).')','display'=>'none'); $a_tab['analytic_div']=array('id'=>'analytic_div'.$div,'label'=>_('Comptabilité Analytique'),'display'=>'none'); +$a_tab['supplemental_doc_div']=array('id'=>'supplemental_doc_div'.$div,'label'=>_('Documents supplémentaires'),'display'=>'none'); //var $g_parameter \Noalyss_Parameter_Folder global $g_parameter; @@ -64,7 +65,11 @@ if ( $div != "popup") : ?>
  • - + + + + +
  • @@ -294,9 +299,17 @@ echo ''; ?> +
    diff --git a/include/template/ledger_detail_sup_files.php b/include/template/ledger_detail_sup_files.php new file mode 100644 index 000000000..6bd2b1f93 --- /dev/null +++ b/include/template/ledger_detail_sup_files.php @@ -0,0 +1,103 @@ + +
    +
    +collect_objects(" where jr_id=$1 order by js_cbc_id", [$jr_id]); + +if ( count($a_row) > 0) +{ + foreach ($a_row as $item) { + $export="export.php?"; + $script="Supplement_Document.delete_document('$gDossier','$div','{$item->js_id}','$jr_id')"; + $rowid=sprintf("row_js_%s_%s",$div,$item->js_id); + // @var $download (url) to send file + $download="export.php?". http_build_query( + [ + "act"=>"RAW:suppl-document" + ,"js_id"=>$item->js_id + ,"gDossier"=>$gDossier + ]); + ?> +
    + +
    + js_description?> +
    +
    + +
    +
    + "RAW:suppl-document" + ,"js_id"=>0 + ,"gDossier"=>$gDossier + ,'operation_id'=>$jr_id + ]); + + * + */ +$javascript=sprintf("Supplement_Document.input_file('%s','%s','%s')", + $gDossier, + $div, + $jr_id); + + $download="export.php?". http_build_query( + [ + "act"=>"RAW:suppl-document" + ,"js_id"=>0 + ,"gDossier"=>$gDossier + ,'operation_id'=>$jr_id + ]); +?> + + +
    +
      +
    • + +
    • +
    +
    \ No newline at end of file diff --git a/include/template/ledger_detail_ven.php b/include/template/ledger_detail_ven.php index 64fcd1f9b..f13d4653c 100644 --- a/include/template/ledger_detail_ven.php +++ b/include/template/ledger_detail_ven.php @@ -105,7 +105,7 @@ $str_anc = ""; $ipaid = new ICheckBox("ipaid", 'paid'); $ipaid->selected = ($obj->det->jr_rapt == 'paid'); echo $ipaid->input(); - if ( DEBUGNOALYSS > 0) echo \Noalyss\Dbg::hidden_info("obj", $obj); + ?> diff --git a/include/template/menu.php b/include/template/menu.php index 64345b00c..9fa4447ad 100644 --- a/include/template/menu.php +++ b/include/template/menu.php @@ -36,7 +36,7 @@ $js=""; $class_list_element="nav-item nav-item-underline"; $class_link="nav-link"; - + $url=""; if ( $amenu[$i]['me_url']!='') { $url=$amenu[$i]['me_url']; @@ -86,6 +86,7 @@ ?> diff --git a/include/template/module.php b/include/template/module.php index 6430c6921..6990a820e 100644 --- a/include/template/module.php +++ b/include/template/module.php @@ -24,7 +24,7 @@ if ( $cn->get_value("select count(*) from profile join profile_user using (p_id) $search_card=new IText('card_search'); $search_card->css_size='97%'; $search_card_js=sprintf('onclick="boxsearch_card(\'%d\')"',dossier::id()); - echo Icon_Action::card( "$('box_search_card').show()"); + echo Icon_Action::card( "$('box_search_card').show();$('box_search_card').setStyle({'z-index':get_next_layer()})"); echo ''; console.error(e.message); } } +var vat_code = new VAT_Code('') diff --git a/include/upgrade.inc.php b/include/upgrade.inc.php index dc2c1495f..28620b488 100644 --- a/include/upgrade.inc.php +++ b/include/upgrade.inc.php @@ -36,7 +36,7 @@ $menu=array( ); $sb=$http->request("sb", "string", "application"); echo '
    '; -echo ShowItem($menu, "H", "nav-item", "nav-link", $sb,"nav nav-pills nav-level2"); +echo show_menu_extension($menu, $sb); echo '
    '; $sc=$http->get("sc", "string", "none"); diff --git a/scenario/LIB/select-box-test.php b/scenario/LIB/select-box-test.php index a739d0213..0e9b64922 100644 --- a/scenario/LIB/select-box-test.php +++ b/scenario/LIB/select-box-test.php @@ -3,69 +3,7 @@ diff --git a/sql/upgrade.sql b/sql/upgrade.sql index e004a0162..13255c7fa 100644 --- a/sql/upgrade.sql +++ b/sql/upgrade.sql @@ -233,7 +233,7 @@ insert into parameter_extra(pe_code,pe_label) values ('COMPANY_LEGAL_REGISTRATIO insert into parameter_extra(pe_code,pe_label) values ('COMPANY_LEGAL_ENTITY','Forme légal de la société (SRL,ASBL,AISBL,...') on conflict do nothing; insert into parameter_extra(pe_code,pe_label) values ('COMPANY_BANK_IBAN','Compte en banque (IBAN)') on conflict do nothing; insert into parameter_extra(pe_code,pe_label) values ('COMPANY_BANK_BIC','BIC Bank Identification Code') on conflict do nothing; -insert into parameter_extra(pe_code,pe_label) values ('COMPANY_UBL_ID','ID PEPPOL') on conflict do nothing; +insert into parameter_extra(pe_code,pe_label) values ('COMPANY_UBL_ID','Identifiant PEPPOL') on conflict do nothing; insert into parameter_extra(pe_code,pe_label) values ('SIREN','n° SIREN') on conflict do nothing; insert into parameter_extra(pe_code,pe_label) values ('SIRET','n° SIRET') on conflict do nothing; @@ -244,23 +244,6 @@ insert into parameter_extra(pe_code,pe_label) values ('SIRET','n° SIRET') on co ALTER TABLE TVA_RATE ADD TVA_PEPPOL_CODE varchar(3); comment on column tva_rate.Tva_peppol_code is 'Code for Peppol : S standard,Z zéro, AE Autoliquidation ,K autoliquidation intra, G : exempté TVA pour export'; -drop VIEW public.v_tva_rate; - -CREATE OR REPLACE VIEW public.v_tva_rate -AS SELECT tva_id, - tva_rate, - tva_code, - tva_label, - tva_comment, - tva_reverse_account, - split_part(tva_poste, ','::text, 1) AS tva_purchase, - split_part(tva_poste, ','::text, 2) AS tva_sale, - tva_both_side, - tva_payment_purchase, - tva_payment_sale, - tva_peppol_code -FROM tva_rate; - create table quantity_code_ref( qc_code text not null primary key, qc_label text not null @@ -303,7 +286,7 @@ comment on sequence seq_doc_type_stdinv is 'Sequence for standard invoice'; INSERT INTO public.menu_ref (me_code, me_menu, me_file, me_url, me_description, me_parameter, me_javascript, me_type, me_description_etendue) -VALUES('RAW:xml-invoice', 'Exporte la facture XML', 'export_xml-invoice.php', NULL, 'export la facture électronique en XML', NULL, NULL, 'PR', NULL); +VALUES('RAW:xml-invoice', 'Exporte la facture XML', 'export_xml-invoice.php', NULL, 'exporte la facture électronique en XML', NULL, NULL, 'PR', NULL); insert into profile_menu (me_code,p_id, p_type_display) select 'RAW:xml-invoice',p_id,'P' from profile; @@ -438,24 +421,14 @@ insert into jnt_fic_attr (fd_id,ad_id,jnt_order) -- 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 + AS $BODY$ declare -/* - * Section for variables - */ -n_card_id int; -vat_number text; -record_card RECORD; -result_fct int; -country_code text; + n_card_id int; + vat_number text; + record_card RECORD; + result_fct int; begin -select pi_value into country_code from parameter_internal where pi_id ='COUNTRY_CODE'; result_fct := 0; @@ -478,4 +451,168 @@ end; $BODY$ LANGUAGE plpgsql; -select comptaproc.update_peppol(); \ No newline at end of file +select comptaproc.update_peppol(); + + +CREATE TABLE public.jrn_sup_document ( + js_id int8 GENERATED BY DEFAULT AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, -- PK + js_mimetype text NOT NULL, -- Mimetype + js_lob oid NOT NULL, -- OID + jr_id int8 NOT NULL, -- FK to jrn + js_filename text not null, + js_description text , + js_cbc_id text, + CONSTRAINT jrn_sup_document_pkey PRIMARY KEY (js_id), + CONSTRAINT jrn_sup_document_jrn_fk FOREIGN KEY (jr_id) REFERENCES public.jrn(jr_id) ON DELETE SET NULL ON UPDATE CASCADE +); +COMMENT ON TABLE public.jrn_sup_document IS 'Supplement document for operation'; + +-- Column comments + +COMMENT ON COLUMN public.jrn_sup_document.js_id IS 'PK'; +COMMENT ON COLUMN public.jrn_sup_document.js_mimetype IS 'Mimetype'; +COMMENT ON COLUMN public.jrn_sup_document.js_lob IS 'OID'; +COMMENT ON COLUMN public.jrn_sup_document.jr_id IS 'FK to jrn'; +COMMENT ON COLUMN public.jrn_sup_document.js_description IS 'Description of document'; +COMMENT ON COLUMN public.jrn_sup_document.js_cbc_id IS 'ID in XML'; + + + +INSERT INTO public.menu_ref (me_code, me_menu, me_file, me_url, me_description, me_parameter, me_javascript, me_type, me_description_etendue) +VALUES('RAW:suppl-document', 'Exporte Document supplementaire', 'export_suppl-document.php', NULL, 'télécharge le document supp', NULL, NULL, 'PR', NULL); + +insert into profile_menu (me_code,p_id, p_type_display) select 'RAW:suppl-document',p_id,'P' from profile; + + +alter table tva_rate add column vx_code text; + +COMMENT ON COLUMN public.tva_rate.vx_code IS 'Peppol: exemption code for VAT'; + + +-- public.vatex_code definition + +-- Drop table + +-- DROP TABLE public.vatex_code; + + +CREATE TABLE public.vatex_code ( vx_code text primary key, vx_country varchar(5) , vx_code_name varchar(256) , vx_description text, vx_remark text); + +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-79-C','eu','Exonération en vertu de l''article 79, point c), de la directive 2006/112/CE du Conseil','Exemptions relatives au remboursement des dépenses.','Le remboursement des dépenses ne constitue pas une exonération au sens de la directive TVA, mais peut être traité comme tel dans le cadre de la norme EN16931.'), + ('VATEX-EU-132','eu','Exonération fondée sur l''article 132 de la directive 2006/112/CE du Conseil','Exemptions pour certaines activités d''intérêt public.',''), + ('VATEX-EU-132-1A','eu','Exonération en vertu de l''article 132, paragraphe 1, point a), de la directive 2006/112/CE du Conseil','La fourniture par les services postaux publics de services autres que le transport de passagers et les services de télécommunications, ainsi que la fourniture de biens accessoires à ces services.',''), + ('VATEX-EU-132-1B','eu','Exonération en vertu de l''article 132, paragraphe 1, point b), de la directive 2006/112/CE du Conseil','Soins hospitaliers et médicaux et activités étroitement liées exercées par des organismes de droit public ou, dans des conditions sociales comparables à celles applicables aux organismes de droit public, par des hôpitaux, des centres de traitement ou de diagnostic médical et d''autres établissements dûment reconnus de nature similaire.',''), + ('VATEX-EU-132-1C','eu','Exonération sur la base de l''article 132, paragraphe 1, point c), de la directive 2006/112/CE du Conseil','La prestation de soins médicaux dans l''exercice des professions médicales et paramédicales telles que définies par l''État membre concerné.',''), + ('VATEX-EU-132-1D','eu','Exonération en vertu de l''article 132, paragraphe 1, point d), de la directive 2006/112/CE du Conseil','L''approvisionnement en organes humains, en sang et en lait.',''), + ('VATEX-EU-132-1E','eu','Exonération en vertu de l''article 132, paragraphe 1, point e), de la directive 2006/112/CE du Conseil','La prestation de services par les techniciens dentaires dans le cadre de leur activité professionnelle et la fourniture de prothèses dentaires par les dentistes et les techniciens dentaires.',''), + ('VATEX-EU-132-1F','eu','Exonération en vertu de l''article 132, paragraphe 1, point f), de la directive 2006/112/CE du Conseil','La prestation de services par des groupements autonomes de personnes, qui exercent une activité exonérée de la TVA ou pour laquelle ils ne sont pas assujettis, dans le but de fournir à leurs membres les services directement nécessaires à l''exercice de cette activité, lorsque ces groupements se contentent de réclamer à leurs membres le remboursement exact de leur part des dépenses communes, à condition que cette exonération ne soit pas susceptible de provoquer des distorsions de concurrence.',''), + ('VATEX-EU-132-1G','eu','Exonération fondée sur l''article 132, paragraphe 1, point g), de la directive 2006/112/CE du Conseil','La fourniture de services et de biens étroitement liés à l''action sociale et à la protection sociale, y compris ceux fournis par les maisons de retraite, par des organismes de droit public ou par d''autres organismes reconnus par l''État membre concerné comme étant consacrés au bien-être social.',''), + ('VATEX-EU-132-1H','eu','Exonération sur la base de l''article 132, paragraphe 1, point h), de la directive 2006/112/CE du Conseil','La fourniture de services et de biens étroitement liés à la protection des enfants et des jeunes par des organismes de droit public ou par d''autres organisations reconnues par l''État membre concerné comme étant consacrées au bien-être social ;',''); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-132-1I','eu','Exonération en vertu de l''article 132, paragraphe 1, point i), de la directive 2006/112/CE du Conseil',' La fourniture d''enseignement aux enfants ou aux jeunes, d''enseignement scolaire ou universitaire, de formation professionnelle ou de reconversion, y compris la fourniture de services et de biens étroitement liés à ces activités, par des organismes de droit public ayant pour but ou par d''autres organismes reconnus par l''État membre concerné comme ayant des objectifs similaires.',''), + ('VATEX-EU-132-1J','eu','Exonération sur la base de l''article 132, paragraphe 1, point j), de la directive 2006/112/CE du Conseil','Cours particuliers dispensés par des enseignants et couvrant l''enseignement scolaire ou universitaire.',''), + ('VATEX-EU-132-1K','eu','Exonération en vertu de l''article 132, paragraphe 1, point k), de la directive 2006/112/CE du Conseil','La mise à disposition de personnel par des institutions religieuses ou philosophiques aux fins des activités visées aux points b), g), h) et i) et dans le but d''assurer le bien-être spirituel.',''), + ('VATEX-EU-132-1L','eu','Exonération en vertu de l''article 132, paragraphe 1, point l), de la directive 2006/112/CE du Conseil','La fourniture de services, et la fourniture de biens qui y sont étroitement liés, à leurs membres dans leur intérêt commun, en contrepartie d''une cotisation fixée conformément à leurs règles, par des organisations sans but lucratif à caractère politique, syndical, religieux, patriotique, philosophique, philanthropique ou civique, à condition que cette exonération ne soit pas susceptible de provoquer des distorsions de concurrence.',''), + ('VATEX-EU-132-1M','eu','Exonération en vertu de l''article 132, paragraphe 1, point m), de la directive 2006/112/CE du Conseil + ','La prestation de certains services étroitement liés au sport ou à l''éducation physique par des organismes sans but lucratif à des personnes participant à des activités sportives ou d''éducation physique.',''), + ('VATEX-EU-132-1N','eu','Exonération en vertu de l''article 132, paragraphe 1, point n), de la directive 2006/112/CE du Conseil','La prestation de certains services culturels et la fourniture de biens étroitement liés à ces services par des organismes de droit public ou d''autres organismes culturels reconnus par l''État membre concerné.',''), + ('VATEX-EU-132-1O','eu','Exonération en vertu de l''article 132, paragraphe 1, point o), de la directive 2006/112/CE du Conseil','La fourniture de services et de biens, par des organisations dont les activités sont exonérées en vertu des points b), g), h), i), l), m) et n), dans le cadre d''événements organisés exclusivement à des fins de collecte de fonds pour leur propre bénéfice, à condition que cette exonération ne soit pas susceptible de provoquer des distorsions de concurrence.',''), + ('VATEX-EU-132-1P','eu','Exonération en vertu de l''article 132, paragraphe 1, point p), de la directive 2006/112/CE du Conseil','Prestation de services de transport de personnes malades ou blessées dans des véhicules spécialement conçus à cet effet, par des organismes dûment agréés.',''), + ('VATEX-EU-132-1Q','eu','Exonération en vertu de l''article 132, paragraphe 1, point q), de la directive 2006/112/CE du Conseil','Les activités, autres que celles à caractère commercial, exercées par les organismes publics de radio et de télévision.',''), + ('VATEX-EU-143','eu','Exonération en vertu de l''article 143 de la directive 2006/112/CE du Conseil','Exonérations à l''importation.',''); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-143-1A','eu','Exonération en vertu de l''article 143, paragraphe 1, point a), de la directive 2006/112/CE du Conseil','Importation définitive de biens dont la livraison par un assujetti serait en tout état de cause exonérée sur leur territoire respectif.',''), + ('VATEX-EU-143-1B','eu','Exonération en vertu de l''article 143, paragraphe 1, point b), de la directive 2006/112/CE du Conseil','L''importation définitive de biens régis par les directives 69/169/CEE (1), 83/181/CEE (2) et 2006/79/CE (3) du Conseil.',''), + ('VATEX-EU-143-1C','eu','Exonération en vertu de l''article 143, paragraphe 1, point c), de la directive 2006/112/CE du Conseil','L''importation définitive de biens, en libre pratique à partir d''un territoire tiers faisant partie du territoire douanier de la Communauté, qui bénéficieraient de l''exonération prévue au point b) s''ils avaient été importés au sens de l''article 30, premier alinéa.',''), + ('VATEX-EU-143-1D','eu','Exonération en vertu de l''article 143, paragraphe 1, point d), de la directive 2006/112/CE du Conseil','L''importation de biens expédiés ou transportés à partir d''un territoire tiers ou d''un pays tiers vers un État membre autre que celui où l''expédition ou le transport des biens prend fin, lorsque la livraison de ces biens par l''importateur désigné ou reconnu comme redevable de la TVA en vertu de l''article 201 est exonérée en vertu de l''article 138.',''), + ('VATEX-EU-143-1E','eu','Exonération en vertu de l''article 143, paragraphe 1, point e), de la directive 2006/112/CE du Conseil','La réimportation, par la personne qui les a exportées, de marchandises dans l''état où elles ont été exportées, lorsque ces marchandises sont exonérées de droits de douane.',''), + ('VATEX-EU-143-1F','eu','Exonération en vertu de l''article 143, paragraphe 1, point f), de la directive 2006/112/CE du Conseil','L''importation, dans le cadre d''accords diplomatiques et consulaires, de marchandises exonérées de droits de douane.',''), + ('VATEX-EU-143-1FA','eu','Exonération en vertu de l''article 143, paragraphe 1, point f bis), de la directive 2006/112/CE du Conseil','L''importation de marchandises par la Communauté européenne, la Communauté européenne de l''énergie atomique, la Banque centrale européenne ou la Banque européenne d''investissement, ou par les organismes créés par les Communautés auxquels s''applique le protocole du 8 avril 1965 sur les privilèges et immunités des Communautés européennes, dans les limites et conditions prévues par ce protocole et les accords pris pour son application ou les accords de siège, dans la mesure où cela n''entraîne pas de distorsion de concurrence ;',''), + ('VATEX-EU-143-1G','eu','Exonération fondée sur l''article 143, paragraphe 1, point g), de la directive 2006/112/CE du Conseil',' L''importation de biens par des organismes internationaux, autres que ceux visés au point f bis), reconnus comme tels par les autorités publiques de l''État membre d''accueil, ou par les membres de ces organismes, dans les limites et conditions fixées par les conventions internationales instituant les organismes ou par les accords de siège ;',''), + ('VATEX-EU-143-1H','eu','Exonération sur la base de l''article 143, paragraphe 1, point h), de la directive 2006/112/CE du Conseil','L''importation de biens, dans les États membres parties au traité de l''Atlantique Nord, par les forces armées d''autres États parties à ce traité pour l''usage de ces forces ou du personnel civil qui les accompagne ou pour l''approvisionnement de leurs mess ou cantines lorsque ces forces participent à l''effort commun de défense.',''), + ('VATEX-EU-143-1I','eu','Exonération sur la base de l''article 143, paragraphe 1, point i), de la directive 2006/112/CE du Conseil','Importation de biens par les forces armées du Royaume-Uni stationnées sur l''île de Chypre en vertu du traité d''établissement concernant la République de Chypre, daté du 16 août 1960, destinés à l''usage de ces forces ou du personnel civil qui les accompagne ou à l''approvisionnement de leurs mess ou cantines.',''); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-143-1J','eu','Exonération en vertu de l''article 143, paragraphe 1, point j), de la directive 2006/112/CE du Conseil','L''importation dans les ports, par les entreprises de pêche maritime, de leurs captures, non transformées ou après avoir subi une conservation en vue de leur commercialisation, mais avant leur livraison.',''), + ('VATEX-EU-143-1K','eu','Exonération en vertu de l''article 143, paragraphe 1, point k), de la directive 2006/112/CE du Conseil','Importation d''or par les banques centrales.',''), + ('VATEX-EU-143-1L','eu','Exonération en vertu de l''article 143, paragraphe 1, point l), de la directive 2006/112/CE du Conseil','Importation de gaz par un réseau de gaz naturel ou tout réseau raccordé à un tel réseau ou alimenté par un navire transportant du gaz dans un réseau de gaz naturel ou tout réseau de gazoduc en amont, d''électricité ou d''énergie thermique ou frigorifique par des réseaux de chauffage ou de refroidissement.',''), + ('VATEX-EU-144','eu','Exonération en vertu de l''article 144 de la directive 2006/112/CE du Conseil','Exonérations pour les services liés à l''importation de biens',''), + ('VATEX-EU-146-1E','eu','Exonération en vertu de l''article 146, paragraphe 1, point e), de la directive 2006/112/CE du Conseil','Exonérations pour les services liés à l''exportation de biens',''), + ('VATEX-EU-148','eu','Exonération en vertu de l''article 148 de la directive 2006/112/CE du Conseil','Exonérations liées au transport international.',''), + ('VATEX-EU-148-A','eu','Exonération en vertu de l''article 148, point a), de la directive 2006/112/CE du Conseil','Fournitures de carburant pour les navires de transport international commercial',''), + ('VATEX-EU-148-B','eu','Exonération en vertu de l''article 148, point b), de la directive 2006/112/CE du Conseil','Fournitures de carburant pour les navires de combat effectuant des transports internationaux.',''), + ('VATEX-EU-148-C','eu','Exonération en vertu de l''article 148, paragraphe c), de la directive 2006/112/CE du Conseil','Entretien, modification, affrètement et location de navires de transport international.',''), + ('VATEX-EU-148-D','eu','Exonération en vertu de l''article 148, paragraphe d), de la directive 2006/112/CE du Conseil','Prestation d''autres services à des navires de transport commercial international.',''); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-148-E','eu','Exonération en vertu de l''article 148, paragraphe e), de la directive 2006/112/CE du Conseil','Fourniture de carburant pour les aéronefs effectuant des vols internationaux.',''), + ('VATEX-EU-148-F','eu','Exonération en vertu de l''article 148, paragraphe f), de la directive 2006/112/CE du Conseil','Entretien, modification, affrètement et location d''aéronefs sur les liaisons internationales.',''), + ('VATEX-EU-148-G','eu','Exonération en vertu de l''article 148, point g), de la directive 2006/112/CE du Conseil','Prestation d''autres services aux aéronefs sur les routes internationales.',''), + ('VATEX-EU-151','eu','Exonération en vertu de l''article 151 de la directive 2006/112/CE du Conseil','Exonérations relatives à certaines opérations assimilées à des exportations.',''), + ('VATEX-EU-151-1A','eu','Exonération en vertu de l''article 151, paragraphe 1, point a), de la directive 2006/112/CE du Conseil','La fourniture de biens ou de services dans le cadre d''accords diplomatiques et consulaires.',''), + ('VATEX-EU-151-1AA','eu','Exonération en vertu de l''article 151, paragraphe 1, point a bis), de la directive 2006/112/CE du Conseil','La livraison de biens ou la prestation de services à la Communauté européenne, à la Communauté européenne de l''énergie atomique, à la Banque centrale européenne ou à la Banque européenne d''investissement, ou aux organismes créés par les Communautés auxquels s''applique le protocole du 8 avril 1965 sur les privilèges et immunités des Communautés européennes, dans les limites et conditions prévues par ledit protocole et les accords pris pour son application ou les accords de siège, dans la mesure où cela n''entraîne pas de distorsion de concurrence.',''), + ('VATEX-EU-151-1B','eu','Exonération fondée sur l''article 151, paragraphe 1, point b), de la directive 2006/112/CE du Conseil','Les livraisons de biens ou les prestations de services effectuées à des organismes internationaux, autres que ceux visés au point a bis), reconnus comme tels par les autorités publiques des États membres d''accueil, et aux membres de ces organismes, dans les limites et conditions prévues par les conventions internationales instituant ces organismes ou par les accords de siège.',''), + ('VATEX-EU-151-1C','eu','Exonération sur la base de l''article 151, paragraphe 1, point c), de la directive 2006/112/CE du Conseil','La fourniture de biens ou de services dans un État membre partie au traité de l''Atlantique Nord, destinés soit aux forces armées d''autres États parties à ce traité pour l''usage de ces forces, soit au personnel civil qui les accompagne, soit à l''approvisionnement de leurs mess ou cantines lorsque ces forces participent à l''effort commun de défense.',''), + ('VATEX-EU-151-1D','eu','Exonération en vertu de l''article 151, paragraphe 1, point d), de la directive 2006/112/CE du Conseil','La livraison de biens ou la prestation de services à un autre État membre, destinés aux forces armées de tout État partie au traité de l''Atlantique Nord, autre que l''État membre de destination lui-même, pour l''usage de ces forces ou du personnel civil qui les accompagne, ou pour l''approvisionnement de leurs mess ou cantines lorsque ces forces participent à l''effort commun de défense.',''), + ('VATEX-EU-151-1E','eu','Exonération en vertu de l''article 151, paragraphe 1, point e), de la directive 2006/112/CE du Conseil','La livraison de biens ou la prestation de services aux forces armées du Royaume-Uni stationnées sur l''île de Chypre en vertu du traité d''établissement concernant la République de Chypre, daté du 16 août 1960, qui sont destinés à l''usage de ces forces ou du personnel civil qui les accompagne, ou à l''approvisionnement de leurs mess ou cantines.',''); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-153','eu','Exonération en vertu de l''article 153 de la directive 2006/112/CE du Conseil','Prestation de services par des intermédiaires agissant au nom et pour le compte d''une autre personne. À l''exclusion des agences de voyages.',''), + ('VATEX-EU-159','eu','Exonération en vertu de l''article 159 de la directive 2006/112/CE du Conseil','Exonérations pour les services liés à la livraison de biens destinés à être placés sous le régime des entrepôts douaniers, des entrepôts autres que les entrepôts douaniers et des régimes similaires.',''), + ('VATEX-EU-309','eu','Exonération en vertu de l''article 309 de la directive 2006/112/CE du Conseil','Services d''agences de voyages fournis en dehors de l''UE.',''), + ('VATEX-EU-AE','eu','Autoliquidation','Prend en charge la règle EN 16931-1 BR-AE-10','À utiliser uniquement avec le code de catégorie TVA AE'), + ('VATEX-EU-D','eu','Acquisition intracommunautaire à partir de moyens de transport d''occasion','Moyens de transport d''occasion - Indication que la TVA a été acquittée conformément aux dispositions transitoires applicables','À utiliser uniquement avec le code de catégorie TVA E'), + ('VATEX-EU-F','eu','Acquisition intracommunautaire de biens d''occasion','Biens d''occasion - Indication que le régime de la marge bénéficiaire pour les biens d''occasion a été appliqué.','À utiliser uniquement avec le code de catégorie TVA E'), + ('VATEX-EU-G','eu','Exportation hors de l''UE','Conforme à la norme EN 16931-1 BR-G-10','À utiliser uniquement avec le code de catégorie TVA G'), + ('VATEX-EU-I','eu','Acquisition intracommunautaire d''œuvres d''art','Œuvres d''art - Indication que le régime de la marge bénéficiaire pour les œuvres d''art a été appliqué.','À utiliser uniquement avec le code de catégorie TVA E'), + ('VATEX-EU-IC','eu','Livraison intracommunautaire','Conforme à la norme EN 16931-1 BR-IC-10','À utiliser uniquement avec le code de catégorie TVA K'), + ('VATEX-EU-J','eu','Acquisition intracommunautaire d''objets de collection et d''antiquités','Objets de collection et antiquités - Indication que le régime de marge de TVA pour les objets de collection et les antiquités a été appliqué.','À utiliser uniquement avec le code de catégorie TVA E'); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-EU-O','eu','Non soumis à la TVA','Conforme à la norme EN 16931-1 BR-O-10','À utiliser uniquement avec le code de catégorie TVA O'), + ('VATEX-FR-FRANCHISE','fr','Franchise de TVA intérieure française','Assujettis à la TVA sur le territoire national qui bénéficient d''une franchise de base (article 293 B du code général des impôts. Dans ce cas, ils sont exonérés de TVA).','Pour la facturation nationale en France'), + ('VATEX-FR-CNWVAT','fr','France nationale Notes de crédit sans TVA, dues au fournisseur pour la perte de TVA liée à la remise','Doctrine administrative BOI TVA DECLA 30 20 20 §260 et 270 pour les notes de crédit et §280 et 290 pour les remises','Pour les notes de crédit nationales uniquement en France'), + ('VATEX-FR-CGI261-1','fr','Exonération sur la base de l''article 261, paragraphe 1, du Code général des impôts (CGI)','Exonération de TVA pour les opérations soumises à d''autres taxes','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-2','fr','Exonération en vertu de l''article 261, paragraphe 2, du Code général des impôts (CGI)','Exonération de TVA pour les activités agricoles et de pêche','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-3','fr','Exonération en vertu de l''article 261, paragraphe 3, du Code général des impôts (CGI)','Exonération de TVA pour les ventes de biens d''occasion','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-4','fr','Exonération en vertu de l''article 261, paragraphe 4, du Code général des impôts (CGI)','Exonération de TVA pour les activités libérales et diverses','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-5','fr','Exonération en vertu de l''article 261, paragraphe 5, du Code général des impôts (CGI)','Exonération de TVA pour les opérations immobilières','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-7','fr','Exonération en vertu de l''article 261, paragraphe 7, du Code général des impôts (CGI)','Exonération de TVA pour les opérations des organismes à but non lucratif','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261-8','fr','Exonération en vertu de l''article 261, paragraphe 8, du Code général des impôts (CGI)','Exonération de TVA, en cas de catastrophe affectant le territoire d''un État membre de l''Union européenne, pour les livraisons de biens et les prestations de services liées à ces livraisons, lorsque l''importation de ces biens par le destinataire de ces livraisons ou par le preneur de ces prestations aurait été exonérée en vertu de l''article 291 II 2° bis du CGI','Uniquement pour la facturation nationale en France'); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-FR-CGI261A','fr','Exonération en vertu de l''article 261 A du Code général des impôts (CGI)','Exonération de TVA pour les opérations effectuées par des personnes morales soumises à l''impôt sur les sociétés qui ont pour objet de céder gratuitement à leurs membres la jouissance de biens mobiliers ou immobiliers (article 239 octies du CGI)','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261B','fr','Exonération en vertu de l''article 261 B du Code général des impôts (CGI)','Exonération de TVA pour les prestations de services fournies à leurs membres par des groupements constitués de personnes physiques ou morales exerçant certaines activités exonérées de TVA sur la base des 4, à l''exception du 10°, et 7 de l''article 261 du CGI (professions et activités diverses, activités d''organismes à but non lucratif)','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261C-1','fr','Exonération sur la base du 1° de l''article 261 C du Code général des impôts (CGI)','Exonération de TVA pour les opérations bancaires et financières','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261C-2','fr','Exonération en vertu du 2° de l''article 261 C du Code général des impôts (CGI)','Exonération de TVA pour les opérations d''assurance et de réassurance et les services connexes effectués par les courtiers et intermédiaires d''assurance','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261C-3','fr','Exonération en vertu du 3° de l''article 261 C du Code général des impôts (CGI)','Exonération de TVA pour les ventes à leur valeur officielle de timbres fiscaux et de timbres-poste ayant une valeur d''affranchissement ou une valeur fiscale en France','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261D-1','fr','Exonération en vertu du 1° de l''article 261 D du Code général des impôts (CGI)','Exonération de TVA pour les locations de terrains et de bâtiments à usage agricole','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261D-1BIS','fr','Exonération en vertu du 1°bis de l''article 261 D du Code général des impôts (CGI)','Exonération de TVA pour les locations de biens immobiliers résultant d''un bail conférant un droit réel','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261D-2','fr','Exonération en vertu du 2° de l''article 261 D du Code général des impôts (CGI)','Exonération de TVA pour certaines locations de terrains non bâtis et de locaux nus, à l''exception des places de stationnement pour véhicules','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261D-3','fr','Exonération en vertu de l''article 261 D, alinéa 3, du Code général des impôts (CGI) Exonération de TVA - Article 261 D-3° du Code Général des Impôts','Exonération de TVA pour la location ou la concession de droits sur les biens visés aux 1° et 2° de l''article 261 D du CGI dans la mesure où ils concernent la gestion d''un portefeuille immobilier','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261D-4','fr','Exonération sur la base du 4° de l''article 261 D du Code général des impôts (CGI)','Exonération de TVA pour les locations occasionnelles, permanentes ou saisonnières de logements meublés ou non meublés à usage d''habitation','Uniquement pour la facturation nationale en France'); +INSERT INTO public.vatex_code (vx_code,vx_country,vx_code_name,vx_description,vx_remark) VALUES + ('VATEX-FR-CGI261E-1','fr','Exonération en vertu du 1° de l''article 261 E du Code général des impôts (CGI)','Exonération de TVA pour l''organisation de jeux de hasard ou d''argent soumis aux prélèvements progressifs','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI261E-2','fr','Exonération en vertu du 2° de l''article 261 E du Code général des impôts (CGI)','Exonération de TVA pour les recettes provenant de l''exploitation de la loterie nationale, des paris hippiques, des paris sur les compétitions sportives et des jeux en ligne, à l''exception des rémunérations perçues par les organisateurs et les intermédiaires participant à l''organisation de ces jeux et paris','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI277A','fr','Exonération en vertu de l''article 277 A du Code général des impôts (CGI)','Régime suspensif de TVA','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI275','fr','Exonération en vertu de l''article 275 du Code général des impôts (CGI)','Achats hors TVA de biens destinés à l''exportation, à une livraison exonérée, à une livraison effectuée sur le territoire d''un autre État membre de l''Union européenne ou à une livraison hors de France, ainsi que les services liés à ces biens','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-298SEXDECIESA','fr','Exonération en vertu de l''article 298 sexdecies A du Code général des impôts (CGI)','Régime spécial applicable à l''or d''investissement','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-CGI295','fr','Exonération en vertu de l''article 295 du Code général des impôts (CGI)','Exonérations de TVA pour les territoires français visés à l''article 349 et à l''article 355, paragraphe 1, du traité sur le fonctionnement de l''Union européenne où la TVA s''applique','Uniquement pour la facturation nationale en France'), + ('VATEX-FR-AE','fr','Exonération en vertu de l''article 283, paragraphe 2, du Code général des impôts (CGI)','Système d''autoliquidation national','Uniquement pour la facturation nationale en France'); + + +ALTER TABLE public.tva_rate ADD CONSTRAINT tva_rate_vatex_code_fk FOREIGN KEY (vx_code) REFERENCES public.vatex_code(vx_code); + +drop VIEW public.v_tva_rate; + +CREATE OR REPLACE VIEW public.v_tva_rate +AS SELECT tva_id, + tva_rate, + tva_code, + tva_label, + tva_comment, + tva_reverse_account, + split_part(tva_poste, ','::text, 1) AS tva_purchase, + split_part(tva_poste, ','::text, 2) AS tva_sale, + tva_both_side, + tva_payment_purchase, + tva_payment_sale, + tva_peppol_code, + vx_code +FROM tva_rate; \ No newline at end of file diff --git a/unit-test/include/class/Acc_TVATest.php b/unit-test/include/class/Acc_TVATest.php index 878e4bfe0..5d22ce835 100644 --- a/unit-test/include/class/Acc_TVATest.php +++ b/unit-test/include/class/Acc_TVATest.php @@ -110,14 +110,60 @@ class Acc_TVATest extends TestCase $vtva_rate->tva_sale="451"; $vtva_rate->tva_both_side="0"; $vtva_rate->tva_rate=0.21; - + $vtva_rate->tva_peppol_code='S'; $tva_rate_mtable=new Tva_Rate_MTable($vtva_rate); $tva_rate_mtable->setPreviousId(0); $check = $tva_rate_mtable->check(); + $this->assertTrue($result==$check," erreur pour $tva_code "); - $this->display_error($tva_rate_mtable); + if ( $result != $check) + { + print "Error for $peppopl_code\n"; + print_r($tva_rate_mtable->aerror); + $this->display_error($tva_rate_mtable); + } } + static function dataCheckVatex() { + return array( + ['S',true,null] + ,['Z',true,null] + ,['A',false,""] + ,['A',true,"XX"] + ); + } + /** + * @brief VATEX Mandatory of tva_peppol_code not in S or Z + * @testdox VATEX Mandatory if tva_peppol_code not S or Z + * @param type $tva_code + * @param type $result + */ + #[DataProvider('dataCheckVatex')] + function testCheckVatex($peppopl_code,$result,$vatex_code) + { + $cn=\Dossier::connect(); + $vtva_rate=new V_Tva_rate_SQL($cn,1); + + $vtva_rate->tva_label="Test"; + $vtva_rate->tva_sale="451"; + $vtva_rate->tva_both_side="0"; + $vtva_rate->tva_rate=0.21; + $vtva_rate->tva_peppol_code=$peppopl_code; + $vtva_rate->vx_code=$vatex_code; + $tva_rate_mtable=new Tva_Rate_MTable($vtva_rate); + $tva_rate_mtable->setPreviousId(1); + + $check = $tva_rate_mtable->check(); + + $this->assertTrue($result==$check," erreur pour $peppopl_code "); + if ( $result != $check) + { + print "Error for $peppopl_code\n"; + print_r($tva_rate_mtable->aerror); + $this->display_error($tva_rate_mtable); + } + } + static function dataBuild() { return array( ['0A',4] diff --git a/unit-test/include/class/acc_ledgerTest.php b/unit-test/include/class/acc_ledgerTest.php index 4960daefa..1b2c62904 100644 --- a/unit-test/include/class/acc_ledgerTest.php +++ b/unit-test/include/class/acc_ledgerTest.php @@ -901,7 +901,9 @@ class Acc_LedgerTest extends TestCase ob_end_clean(); \Noalyss\Facility::save_file(__DIR__."/file", "acc_ledger-input_new.html", $result); $size=filesize(__DIR__."/file/acc_ledger-input_new.html"); - $this->assertTrue($size == 16075 ," output input_new is $size not what it is expected"); + $expected=15985; + $delta =$size-$expected; + $this->assertTrue($delta == 0 ," output input_new is $size expected $expected not what it is expected DELTA=$delta, file to check ".__DIR__."/file/acc_ledger-input_new.html"); } diff --git a/unit-test/include/class/acc_ledger_searchTest.php b/unit-test/include/class/acc_ledger_searchTest.php index 062ec46ea..f2609c53c 100644 --- a/unit-test/include/class/acc_ledger_searchTest.php +++ b/unit-test/include/class/acc_ledger_searchTest.php @@ -89,7 +89,9 @@ class Acc_Ledger_searchTest extends TestCase $r=$ledger->display_search_form(); \Noalyss\Facility::save_file(__DIR__."/file", "acc_ledger_search-test_display_search_form.html", $r); $filesize=strlen($r); - $this->assertTrue($filesize==10971,"Size of the html string for display_search_form see " + $expected=10971; + $delta =$filesize-$expected; + $this->assertTrue($delta == 0,"Size of the html string for display_search_form see delta = $delta , size=$filesize, expected=$expected " . __DIR__."/file/acc_ledger_search-test_display_search_form.html "); } /**