From 7c2b5b614f63611e8cfc28cbdfb7977f3054ef2e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Sun, 25 Oct 2020 19:13:09 +0100 Subject: [PATCH 001/184] NEW: preload product description on selection for customer propal/order/invoice --- htdocs/comm/propal/card.php | 7 +++- htdocs/commande/card.php | 5 +++ htdocs/compta/facture/card.php | 5 +++ htdocs/contrat/card.php | 6 ++++ htdocs/core/tpl/objectline_create.tpl.php | 40 ++++++++++++++++------- htdocs/fourn/facture/card.php | 5 +++ htdocs/product/ajax/products.php | 35 ++++++++++++++++++-- 7 files changed, 87 insertions(+), 16 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 4a4cf3c37dd..3a9fc38fbaf 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -995,11 +995,16 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } - $desc = (!empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + $desc = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; } else { $desc = $prod->description; } + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc) { + $product_desc=''; + } + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; else $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 596fe4e94bc..585b85def0b 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -854,6 +854,11 @@ if (empty($reshook)) $desc = $prod->description; } + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc) { + $product_desc=''; + } + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; else $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 94f817114aa..6b56d39ba3f 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2068,6 +2068,11 @@ if (empty($reshook)) $desc = $prod->description; } + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc) { + $product_desc=''; + } + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; else $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 64b3275379a..f3dc0355331 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -499,6 +499,12 @@ if (empty($reshook)) } $desc = $prod->description; + + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc) { + $product_desc=''; + } + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; else $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index d177ce7637c..ec73bf9725b 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -514,13 +514,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) global->DISPLAY_MARGIN_RATES)) { ?> $("input[name='np_marginRate']:first").blur(function(e) { - return checkFreeLine(e, "np_marginRate"); + return checkFreeLine(e, "np_marginRate"); }); global->DISPLAY_MARK_RATES)) { ?> $("input[name='np_markRate']:first").blur(function(e) { - return checkFreeLine(e, "np_markRate"); + return checkFreeLine(e, "np_markRate"); }); rights->margins->creer) var rate = $("input[name='"+npRate+"']:first"); if (rate.val() == '') - return true; + return true; if (! $.isNumeric(rate.val().replace(',','.'))) { - alert('trans("rateMustBeNumeric")); ?>'); - e.stopPropagation(); - setTimeout(function () { rate.focus() }, 50); - return false; + alert('trans("rateMustBeNumeric")); ?>'); + e.stopPropagation(); + setTimeout(function () { rate.focus() }, 50); + return false; } if (npRate == "np_markRate" && rate.val() >= 100) { - alert('trans("markRateShouldBeLesserThan100")); ?>'); - e.stopPropagation(); - setTimeout(function () { rate.focus() }, 50); - return false; + alert('trans("markRateShouldBeLesserThan100")); ?>'); + e.stopPropagation(); + setTimeout(function () { rate.focus() }, 50); + return false; } var price = 0; @@ -659,7 +659,6 @@ if (!empty($usemargins) && $user->rights->margins->creer) ?> var pbq = parseInt($('option:selected', this).attr('data-pbq')); /* If product was selected with a HTML select */ if (isNaN(pbq)) { pbq = jQuery('#idprod').attr('data-pbq'); } /* If product was selected with a HTML input with autocomplete */ - //console.log(pbq); if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0) { @@ -675,6 +674,23 @@ if (!empty($usemargins) && $user->rights->margins->creer) function(data) { console.log("Load unit price end, we got value "+data.price_ht); jQuery("#price_ht").val(data.price_ht); + global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { ?> + var proddesc = data.desc_trans; + + var proddesc = data.desc; + + console.log("Load desciption into text area : "+proddesc); + global->FCKEDITOR_ENABLE_DETAILS)) { ?> + if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") + { + var editor = CKEDITOR.instances['dp_desc']; + if (editor) { + editor.setData(proddesc); + } + } + + jQuery('#dp_desc').text(proddesc); + }, 'json' ); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 542a4a09274..45fb10b525a 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1294,6 +1294,11 @@ if (empty($reshook)) $desc = $productsupplier->desc_supplier; } else $desc = $productsupplier->description; + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc) { + $product_desc=''; + } + if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index 7441d88abc0..273eef35300 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -71,7 +71,9 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { $outref = $object->ref; $outlabel = $object->label; + $outlabel_trans =''; $outdesc = $object->description; + $outdesc_trans =''; $outtype = $object->type; $outqty = 1; $outdiscount = 0; @@ -79,10 +81,25 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) $found = false; $price_level = 1; - if ($socid > 0 && !empty($conf->global->PRODUIT_MULTIPRICES)) { + + if ($socid > 0) { $thirdpartytemp = new Societe($db); $thirdpartytemp->fetch($socid); - $price_level = $thirdpartytemp->price_level; + //Load translation description and label + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $newlang = $thirdpartytemp->default_lang; + + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + $outdesc_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["description"])) ? $object->multilangs[$outputlangs->defaultlang]["description"] : $object->description; + $outlabel_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["label"])) ? $object->multilangs[$outputlangs->defaultlang]["label"] : $object->label; + } + } + + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $price_level = $thirdpartytemp->price_level; + } } // Price by qty @@ -158,7 +175,19 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) $outtva_tx = $object->tva_tx; } - $outjson = array('ref' => $outref, 'label' => $outlabel, 'desc' => $outdesc, 'type' => $outtype, 'price_ht' => $outprice_ht, 'price_ttc' => $outprice_ttc, 'pricebasetype' => $outpricebasetype, 'tva_tx' => $outtva_tx, 'qty' => $outqty, 'discount' => $outdiscount); + $outjson = array( + 'ref' => $outref, + 'label' => $outlabel, + 'label_trans' => $outlabel_trans, + 'desc' => $outdesc, + 'desc_trans' => $outdesc_trans, + 'type' => $outtype, + 'price_ht' => $outprice_ht, + 'price_ttc' => $outprice_ttc, + 'pricebasetype' => $outpricebasetype, + 'tva_tx' => $outtva_tx, + 'qty' => $outqty, + 'discount' => $outdiscount); } echo json_encode($outjson); From 925dfd36b5d4559a9075c218d40250fde8ff39ea Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Sun, 25 Oct 2020 19:15:10 +0100 Subject: [PATCH 002/184] syntax --- htdocs/fourn/facture/card.php | 5 ----- htdocs/product/ajax/products.php | 9 +++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 45fb10b525a..542a4a09274 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1294,11 +1294,6 @@ if (empty($reshook)) $desc = $productsupplier->desc_supplier; } else $desc = $productsupplier->description; - //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time - if ($product_desc==$desc) { - $product_desc=''; - } - if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index 273eef35300..c2b698c8e04 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -85,6 +85,11 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) if ($socid > 0) { $thirdpartytemp = new Societe($db); $thirdpartytemp->fetch($socid); + + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $price_level = $thirdpartytemp->price_level; + } + //Load translation description and label if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { $newlang = $thirdpartytemp->default_lang; @@ -96,10 +101,6 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) $outlabel_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["label"])) ? $object->multilangs[$outputlangs->defaultlang]["label"] : $object->label; } } - - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $price_level = $thirdpartytemp->price_level; - } } // Price by qty From 76824c868bdadc3268cfab95a4b49820bfaa224d Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 26 Oct 2020 16:31:07 +0100 Subject: [PATCH 003/184] clean get price for fourn and labal for supplier coducment --- htdocs/core/class/html.form.class.php | 30 +++++++- htdocs/core/lib/ajax.lib.php | 40 ++++++++--- htdocs/core/tpl/objectline_create.tpl.php | 83 +++++++++++++++++------ htdocs/fourn/commande/card.php | 4 +- htdocs/fourn/facture/card.php | 2 +- htdocs/product/fournisseurs.php | 2 +- 6 files changed, 127 insertions(+), 34 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index bf52ff5871a..397d1a008cf 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2737,6 +2737,12 @@ class Form $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,"; $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,"; $sql .= " pfp.supplier_reputation"; + // if we use supplier description of the products + if (!empty($conf->global->PRODUIT_FOURN_TEXTS)) { + $sql .= " ,pfp.desc_fourn as description"; + } else { + $sql .= " ,p.description"; + } // Units if ($conf->global->PRODUCT_USE_UNITS) { $sql .= ", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units"; @@ -2766,7 +2772,11 @@ class Form foreach ($scrit as $crit) { if ($i > 0) $sql .= " AND "; - $sql .= "(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%')"; + $sql .= "(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%'"; + if (!empty($conf->global->PRODUIT_FOURN_TEXTS)) { + $sql .= " OR pfp.desc_fourn LIKE '".$this->db->escape($prefix.$crit)."%'"; + } + $sql .= ")"; $i++; } if (count($scrit) > 1) $sql .= ")"; @@ -2956,8 +2966,9 @@ class Form if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt .= ' disabled'; if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0) { - $opt .= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqup="'.$objp->unitprice.'" data-pbqpercent="'.$objp->remise_percent.'"'; + $opt .= ' data-qty="'.$objp->quantity.'" data-up="'.$objp->unitprice.'" data-discount="'.$outdiscount.'"'; } + $opt .= ' data-description="'.dol_escape_htmltag($objp->description).'"'; $opt .= ' data-html="'.dol_escape_htmltag($optlabel).'"'; $opt .= '>'; @@ -2971,7 +2982,20 @@ class Form // "key" value of json key array is used by jQuery automatically as selected value // "label" value of json key array is used by jQuery automatically as text for combo box $out .= $opt; - array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'up'=>$objp->unitprice, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice) ?true:false))); + array_push($outarray, + array('key'=>$outkey, + 'value'=>$outref, + 'label'=>$outval, + 'qty'=>$outqty, + 'up'=>$objp->unitprice, + 'discount'=>$outdiscount, + 'type'=>$outtype, + 'duration_value'=>$outdurationvalue, + 'duration_unit'=>$outdurationunit, + 'disabled'=>(empty($objp->idprodfournprice) ?true:false), + 'description'=>$objp->description + ) + ); // Exemple of var_dump $outarray // array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp" // ["label"]=>string(76) "ppp (fff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)" diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 10fa477600a..9b225967eb1 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -134,7 +134,11 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen } return { label: label, value: item.value, id: item.key, disabled: item.disabled, update: update, textarea: textarea, - pbq: item.pbq, type: item.type, qty: item.qty, discount: item.discount, pricebasetype: item.pricebasetype, price_ht: item.price_ht, price_ttc: item.price_ttc } + pbq: item.pbq, + type: item.type, qty: item.qty, discount: item.discount, + pricebasetype: item.pricebasetype, price_ht: item.price_ht, + price_ttc: item.price_ttc, + up: item.up, description : item.description} })); } else console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array."); @@ -146,14 +150,34 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen console.log("Call change on input '.$htmlname.' because of select definition of autocomplete select call on input#search_'.$htmlname.'"); console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective"); - //console.log(ui.item); - $("#'.$htmlname.'").attr("data-pbq", ui.item.pbq); - $("#'.$htmlname.'").attr("data-pbqup", ui.item.price_ht); - $("#'.$htmlname.'").attr("data-pbqbase", ui.item.pricebasetype); - $("#'.$htmlname.'").attr("data-pbqqty", ui.item.qty); - $("#'.$htmlname.'").attr("data-pbqpercent", ui.item.discount); + console.log(ui.item); + //For supplier price + $("#'.$htmlname.'").attr("data-up", ui.item.up); + $("#'.$htmlname.'").attr("data-discount", ui.item.discount); + $("#'.$htmlname.'").attr("data-qty", ui.item.qty); + $("#'.$htmlname.'").attr("data-description", ui.item.description); - $("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value + //For customer price + '; + + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { + $script .= ' + $("#' . $htmlname . '").attr("data-pbq", ui.item.pbq); + $("#' . $htmlname . '").attr("data-pbqup", ui.item.price_ht); + $("#' . $htmlname . '").attr("data-pbqbase", ui.item.pricebasetype); + $("#' . $htmlname . '").attr("data-pbqqty", ui.item.qty); + $("#' . $htmlname . '").attr("data-pbqpercent", ui.item.discount); + '; + } else { + $script .= ' + $("#' . $htmlname . '").attr("data-up", ui.item.price_ht); + $("#' . $htmlname . '").attr("data-base", ui.item.pricebasetype); + $("#' . $htmlname . '").attr("data-qty", ui.item.qty); + $("#' . $htmlname . '").attr("data-discount", ui.item.discount); + '; + } + $script .= ' + $("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value // Disable an element if (options.option_disabled) { console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index ec73bf9725b..ba6b4e1bb1b 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -602,39 +602,39 @@ if (!empty($usemargins) && $user->rights->margins->creer) }); $("#prod_entry_mode_free").on( "click", function() { - setforfree(); + setforfree(); }); $("#select_type").change(function() { - setforfree(); + setforfree(); if (jQuery('#select_type').val() >= 0) { /* focus work on a standard textarea but not if field was replaced with CKEDITOR */ - jQuery('#dp_desc').focus(); - /* focus if CKEDITOR */ - if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") - { - var editor = CKEDITOR.instances['dp_desc']; - if (editor) { editor.focus(); } - } + jQuery('#dp_desc').focus(); + /* focus if CKEDITOR */ + if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") + { + var editor = CKEDITOR.instances['dp_desc']; + if (editor) { editor.focus(); } + } } console.log("Hide/show date according to product type"); if (jQuery('#select_type').val() == '0') { - jQuery('#trlinefordates').hide(); - jQuery('.divlinefordates').hide(); + jQuery('#trlinefordates').hide(); + jQuery('.divlinefordates').hide(); } else { - jQuery('#trlinefordates').show(); - jQuery('.divlinefordates').show(); + jQuery('#trlinefordates').show(); + jQuery('.divlinefordates').show(); } }); $("#prod_entry_mode_predef").on( "click", function() { - console.log("click prod_entry_mode_predef"); - setforpredef(); - jQuery('#trlinefordates').show(); + console.log("click prod_entry_mode_predef"); + setforpredef(); + jQuery('#trlinefordates').show(); }); rights->margins->creer) 'json' ); } - rights->margins->creer) @@ -804,7 +804,10 @@ if (!empty($usemargins) && $user->rights->margins->creer) } ?> - /* To process customer price per quantity (CUSTOMER_PRICE_PER_QTY works only if combo product is not an ajax after x key pressed) */ + global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) + {?> + /* To process customer price per quantity (PRODUIT_CUSTOMER_PRICES_BY_QTY works only if combo product is not an ajax after x key pressed) */ var pbq = parseInt($('option:selected', this).attr('data-pbq')); // When select is done from HTML select if (isNaN(pbq)) { pbq = jQuery('#idprod').attr('data-pbq'); } // When select is done from HTML input with autocomplete var pbqup = parseFloat($('option:selected', this).attr('data-pbqup')); @@ -816,7 +819,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent')); if (isNaN(pbqpercent)) { pbqpercent = jQuery('#idprod').attr('data-pbqpercent'); } - if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0) + if ((jQuery('#idprod').val() > 0) && ! isNaN(pbq) && pbq > 0) { var pbqupht = pbqup; /* TODO support of price per qty TTC not yet available */ @@ -832,6 +835,48 @@ if (!empty($usemargins) && $user->rights->margins->creer) jQuery("#remise_percent").val(pbqpercent); } } + + //Deal with supplier + if (jQuery('#idprodfournprice').val() >0) + { + var up = parseFloat($('option:selected', this).attr('data-up')); // When select is done from HTML select + if (isNaN(up)) { up = parseFloat(jQuery('#idprodfournprice').attr('data-up'));} // When select is done from HTML input with autocomplete + + var qty = parseFloat($('option:selected', this).attr('data-qty')); + if (isNaN(qty)) { qty = parseFloat(jQuery('#idprodfournprice').attr('data-qty'));} + + var discount = parseFloat($('option:selected', this).attr('data-discount')); + if (isNaN(discount)) { discount = parseFloat(jQuery('#idprodfournprice').attr('data-discount'));} + + var description = $('option:selected', this).attr('data-description'); + if (typeof description == 'undefined') { description = jQuery('#idprodfournprice').attr('data-description'); } + console.log("We find supplier price :"+up+" qty: "+qty+" discount: "+discount+" for product "+jQuery('#idprodfournprice').val()); + + jQuery("#price_ht").val(up); + if (jQuery("#qty").val() < qty) + { + jQuery("#qty").val(qty); + } + if (jQuery("#remise_percent").val() < discount) + { + jQuery("#remise_percent").val(discount); + } + + console.log("Load desciption into text area : "+description); + global->FCKEDITOR_ENABLE_DETAILS)) { ?> + if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") + { + var editor = CKEDITOR.instances['dp_desc']; + if (editor) { + editor.setData(description); + } + } + + jQuery('#dp_desc').text(description); + + } else { jQuery("#pbq").val(''); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index e202b3e8efd..e5ddc3b1b75 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -356,7 +356,7 @@ if (empty($reshook)) // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOST('dp_desc') ?GETPOST('dp_desc') : ''); + $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); $prod_entry_mode = GETPOST('prod_entry_mode'); @@ -475,7 +475,7 @@ if (empty($reshook)) $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); } - $desc = (!empty($productsupplier->multilangs [$outputlangs->defaultlang] ["description"])) ? $productsupplier->multilangs [$outputlangs->defaultlang] ["description"] : $productsupplier->description; + $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description; } else { $desc = $productsupplier->description; } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index c304a4edce7..3f9ea28c420 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1180,7 +1180,7 @@ if (empty($reshook)) // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOST('dp_desc') ?GETPOST('dp_desc') : ''); + $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index b9a8d6c3b68..41c38c82ba7 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -166,7 +166,7 @@ if (empty($reshook)) $price_expression = GETPOST('eid', 'int') ? GETPOST('eid', 'int') : ''; // Discard expression if not in expression mode $delivery_time_days = GETPOST('delivery_time_days', 'int') ? GETPOST('delivery_time_days', 'int') : ''; $supplier_reputation = GETPOST('supplier_reputation'); - $supplier_description = GETPOST('supplier_description', 'alpha'); + $supplier_description = GETPOST('supplier_description', 'restricthtml'); $barcode = GETPOST('barcode', 'alpha'); $fk_barcode_type = GETPOST('fk_barcode_type', 'int'); $packaging = price2num(GETPOST("packaging", 'alphanohtml'), 'MS'); From a53e9077069e4ab467ac94f90a527b8991d3204b Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 26 Oct 2020 15:32:00 +0000 Subject: [PATCH 004/184] Fixing style errors. --- htdocs/core/tpl/objectline_create.tpl.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index ba6b4e1bb1b..c69b57a90d0 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -695,7 +695,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) 'json' ); } - rights->margins->creer) @@ -835,7 +835,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) jQuery("#remise_percent").val(pbqpercent); } } - //Deal with supplier From 9aa3368627a052592a342cdeb41dc22d279444fd Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 26 Oct 2020 16:33:13 +0100 Subject: [PATCH 005/184] syntax --- htdocs/core/lib/ajax.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 9b225967eb1..f8ec1d5ead1 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -150,7 +150,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen console.log("Call change on input '.$htmlname.' because of select definition of autocomplete select call on input#search_'.$htmlname.'"); console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective"); - console.log(ui.item); + //console.log(ui.item); //For supplier price $("#'.$htmlname.'").attr("data-up", ui.item.up); $("#'.$htmlname.'").attr("data-discount", ui.item.discount); From 2c772cd8bb2b046e5490d3f0f73db6bd9dc2876b Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 27 Oct 2020 09:52:04 +0100 Subject: [PATCH 006/184] try to make it work for experimental PRODUIT_CUSTOMER_PRICES_BY_QTY option --- htdocs/core/class/html.form.class.php | 45 +++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 397d1a008cf..ff83173be5e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2150,7 +2150,9 @@ class Form if (!empty($conf->global->MAIN_MULTILANGS)) { $sql .= ", pl.label as label_translated"; + $sql .= ", pl.description as description_translated"; $selectFields .= ", label_translated"; + $selectFields .= ", description_translated"; } // Price by quantity if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) @@ -2190,7 +2192,18 @@ class Form // Multilang : we add translation if (!empty($conf->global->MAIN_MULTILANGS)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='".$this->db->escape($langs->getDefaultLang())."'"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid "; + if (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE) && !empty($socid)) { + $soc = new Societe($db); + $result = $soc->fetch($socid); + if ($result > 0 && !empty($soc->default_lang)) { + $sql .= " AND pl.lang='" . $this->db->escape($soc->default_lang) . "'"; + } else { + $sql .= " AND pl.lang='".$this->db->escape($langs->getDefaultLang())."'"; + } + } else { + $sql .= " AND pl.lang='".$this->db->escape($langs->getDefaultLang())."'"; + } } if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { @@ -2403,7 +2416,9 @@ class Form $outval = ''; $outref = ''; $outlabel = ''; + $outlabel_translated = ''; $outdesc = ''; + $outdesc_translated = ''; $outbarcode = ''; $outorigin = ''; $outtype = ''; @@ -2424,6 +2439,11 @@ class Form $outref = $objp->ref; $outlabel = $objp->label; $outdesc = $objp->description; + if (!empty($conf->global->MAIN_MULTILANGS)) + { + $outlabel_translated = $objp->label_translated; + $outdesc_translated = $objp->description_translated; + } $outbarcode = $objp->barcode; $outorigin = $objp->fk_country; $outpbq = empty($objp->price_by_qty_rowid) ? '' : $objp->price_by_qty_rowid; @@ -2485,6 +2505,10 @@ class Form elseif ($objp->stock <= 0) $opt .= ' class="product_line_stock_too_low"'; } } + if (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $opt .= ' data-labeltrans="'.$outlabel_translated.'"'; + $opt .= ' data-desctrans="'.dol_escape_htmltag($outdesc_translated).'"'; + } $opt .= '>'; $opt .= $objp->ref; if ($outbarcode) $opt .= ' ('.$outbarcode.')'; @@ -2655,7 +2679,24 @@ class Form } $opt .= "\n"; - $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'pbq'=>$outpbq); + $optJson = array( + 'key'=>$outkey, + 'value'=>$outref, + 'label'=>$outval, + 'label2'=>$outlabel, + 'desc'=>$outdesc, + 'type'=>$outtype, + 'price_ht'=>price2num($outprice_ht), + 'price_ttc'=>price2num($outprice_ttc), + 'pricebasetype'=>$outpricebasetype, + 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, + 'discount'=>$outdiscount, + 'duration_value'=>$outdurationvalue, + 'duration_unit'=>$outdurationunit, + 'pbq'=>$outpbq, + 'labeltrans'=>$outlabel_translated, + 'desctrans'=>$outdesc_translated + ); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps From d77a0b40a8923049710455d633911416cd66ada8 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 28 Oct 2020 16:37:41 +0100 Subject: [PATCH 007/184] tested and approuve feaure #15036 --- htdocs/comm/propal/card.php | 4 +- htdocs/commande/card.php | 4 +- htdocs/compta/facture/card.php | 4 +- htdocs/contrat/card.php | 4 +- htdocs/core/tpl/objectline_create.tpl.php | 65 +++++++++++++++++------ htdocs/fourn/commande/card.php | 8 ++- htdocs/fourn/facture/card.php | 7 ++- htdocs/langs/en_US/admin.lang | 4 +- htdocs/product/admin/product.php | 23 ++++++++ htdocs/product/ajax/products.php | 3 ++ 10 files changed, 98 insertions(+), 28 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index f03986d471c..47dd722b5b1 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -793,7 +793,7 @@ if (empty($reshook)) } elseif ($action == 'addline' && $usercancreate) { // Add line // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOSTISSET('dp_desc') ?GETPOST('dp_desc', 'restricthtml') : ''); + $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $price_ht = price2num(GETPOST('price_ht')); $price_ht_devise = price2num(GETPOST('multicurrency_price_ht')); $prod_entry_mode = GETPOST('prod_entry_mode'); @@ -1001,7 +1001,7 @@ if (empty($reshook)) } //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time - if ($product_desc==$desc) { + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { $product_desc=''; } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 6572a383532..1bdce17f564 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -640,7 +640,7 @@ if (empty($reshook)) // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOST('dp_desc') ?GETPOST('dp_desc') : ''); + $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $price_ht = GETPOST('price_ht'); $price_ht_devise = GETPOST('multicurrency_price_ht'); $prod_entry_mode = GETPOST('prod_entry_mode'); @@ -855,7 +855,7 @@ if (empty($reshook)) } //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time - if ($product_desc==$desc) { + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { $product_desc=''; } diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 80e60dd8784..4602e968220 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1902,7 +1902,7 @@ if (empty($reshook)) // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOST('dp_desc', 'none') ?GETPOST('dp_desc', 'restricthtml') : ''); + $product_desc =(GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $price_ht = price2num(GETPOST('price_ht')); $price_ht_devise = price2num(GETPOST('multicurrency_price_ht')); $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha'); @@ -2073,7 +2073,7 @@ if (empty($reshook)) } //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time - if ($product_desc==$desc) { + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { $product_desc=''; } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 034709ef110..3265e2f5866 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -383,7 +383,7 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; - $product_desc = (GETPOST('dp_desc') ?GETPOST('dp_desc') : ''); + $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $price_ht = price2num(GETPOST('price_ht')); $price_ht_devise = price2num(GETPOST('multicurrency_price_ht')); if (GETPOST('prod_entry_mode', 'alpha') == 'free') @@ -501,7 +501,7 @@ if (empty($reshook)) $desc = $prod->description; //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time - if ($product_desc==$desc) { + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { $product_desc=''; } diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index c69b57a90d0..f1faf50e991 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -674,13 +674,18 @@ if (!empty($usemargins) && $user->rights->margins->creer) function(data) { console.log("Load unit price end, we got value "+data.price_ht); jQuery("#price_ht").val(data.price_ht); - global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { ?> + global->PRODUIT_AUTOFILL_DESC)) { + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { ?> var proddesc = data.desc_trans; - + var proddesc = data.desc; - + console.log("Load desciption into text area : "+proddesc); - global->FCKEDITOR_ENABLE_DETAILS)) { ?> + global->FCKEDITOR_ENABLE_DETAILS)) { ?> if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") { var editor = CKEDITOR.instances['dp_desc']; @@ -688,9 +693,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) editor.setData(proddesc); } } - + jQuery('#dp_desc').text(proddesc); - + + }, 'json' ); @@ -834,7 +843,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) { jQuery("#remise_percent").val(pbqpercent); } - } + } else { jQuery("#pbq").val(''); } @@ -850,8 +859,6 @@ if (!empty($usemargins) && $user->rights->margins->creer) var discount = parseFloat($('option:selected', this).attr('data-discount')); if (isNaN(discount)) { discount = parseFloat(jQuery('#idprodfournprice').attr('data-discount'));} - var description = $('option:selected', this).attr('data-description'); - if (typeof description == 'undefined') { description = jQuery('#idprodfournprice').attr('data-description'); } console.log("We find supplier price :"+up+" qty: "+qty+" discount: "+discount+" for product "+jQuery('#idprodfournprice').val()); jQuery("#price_ht").val(up); @@ -864,24 +871,48 @@ if (!empty($usemargins) && $user->rights->margins->creer) jQuery("#remise_percent").val(discount); } + global->PRODUIT_AUTOFILL_DESC)) { + ?> + var description = $('option:selected', this).attr('data-description'); + if (typeof description == 'undefined') { description = jQuery('#idprodfournprice').attr('data-description'); } + console.log("Load desciption into text area : "+description); - global->FCKEDITOR_ENABLE_DETAILS)) { ?> + global->FCKEDITOR_ENABLE_DETAILS)) { ?> if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") { var editor = CKEDITOR.instances['dp_desc']; if (editor) { - editor.setData(description); + editor.setData(description); } } - + jQuery('#dp_desc').text(description); - - } - else - { - jQuery("#pbq").val(''); + + } else if (jQuery('#idprodfournprice').length > 0) { + global->PRODUIT_AUTOFILL_DESC)) { + if (!empty($conf->global->FCKEDITOR_ENABLE_DETAILS)) { ?> + if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") + { + var editor = CKEDITOR.instances['dp_desc']; + if (editor) { + editor.setData(''); + } + } + + jQuery('#dp_desc').text(''); + } + /* To set focus */ if (jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val() > 0) { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 42817e2ea28..f7c963f5e29 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -484,7 +484,13 @@ if (empty($reshook)) $desc = $productsupplier->desc_supplier; } - if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { + $product_desc=''; + } + + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; + if (!empty($product_desc) && trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; if ($price_ht != '' || $price_ht_devise != '') { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 9849e3b6223..a6bc58879c1 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1294,7 +1294,12 @@ if (empty($reshook)) $desc = $productsupplier->desc_supplier; } else $desc = $productsupplier->description; - if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); + //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time + if ($product_desc==$desc && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) { + $product_desc=''; + } + if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) $desc = $product_desc; + if (!empty($product_desc) && trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; if ($price_ht != '' || $price_ht_devise != '') { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index e47390b9ce0..c2bcdef711f 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1587,6 +1587,8 @@ ServiceSetup=Services module setup ProductServiceSetup=Products and Services modules setup NumberOfProductShowInSelect=Maximum number of products to show in combo select lists (0=no limit) ViewProductDescInFormAbility=Display product descriptions in forms (otherwise shown in a tooltip popup) +DoNotAddProductDescAtAddLines=Do not add product description (from product card) on submit add lines on forms +OnProductSelectAddProductDesc=On product selection in forms get the production description into description line MergePropalProductCard=Activate in product/service Attached Files tab an option to merge product PDF document to proposal PDF azur if product/service is in the proposal ViewProductDescInThirdpartyLanguageAbility=Display products descriptions in the language of the third party UseSearchToSelectProductTooltip=Also if you have a large number of products (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. @@ -2067,4 +2069,4 @@ TemplateDeleted=Template deleted MailToSendEventPush=Event reminder email SwitchThisForABetterSecurity=Switching this value to %s is recommended for more security DictionaryProductNature= Nature of product -CountryIfSpecificToOneCountry=Country (if specific to a given country) \ No newline at end of file +CountryIfSpecificToOneCountry=Country (if specific to a given country) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 313a27884ff..e7003c6ee47 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -145,6 +145,12 @@ if ($action == 'other') $value = GETPOST('activate_useProdFournDesc', 'alpha'); $res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value, 'chaine', 0, '', $conf->entity); + $value = GETPOST('activate_FillProductDescAuto', 'alpha'); + $res = dolibarr_set_const($db, "PRODUIT_AUTOFILL_DESC", $value, 'chaine', 0, '', $conf->entity); + + $value = GETPOST('activate_DoNotAddStdProductDescOnAddLine', 'alpha'); + $res = dolibarr_set_const($db, "MAIN_NO_CONCAT_DESCRIPTION", $value, 'chaine', 0, '', $conf->entity); + if ($value) { $sql_test = "SELECT count(desc_fourn) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; $resql = $db->query($sql_test); @@ -630,6 +636,23 @@ print $form->selectyesno("activate_viewProdDescInForm", $conf->global->PRODUIT_D print ''; print ''; +// Do Not Add Product description on add lines +print ''; +print ''.$langs->trans("DoNotAddProductDescAtAddLines").''; +print ''; +print $form->selectyesno("activate_DoNotAddStdProductDescOnAddLine", $conf->global->MAIN_NO_CONCAT_DESCRIPTION, 1); +print ''; +print ''; + +// Do Not Add Product description on add lines +print ''; +print ''.$langs->trans("OnProductSelectAddProductDesc").''; +print ''; +print $form->selectyesno("activate_FillProductDescAuto", $conf->global->PRODUIT_AUTOFILL_DESC, 1); +print ''; +print ''; + + // Activate propal merge produt card /* Kept as hidden feature only. PRODUIT_PDF_MERGE_PROPAL can be added manually. Still did not understand how this feature works. diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index c2b698c8e04..40249e4041e 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -99,6 +99,9 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) $outputlangs->setDefaultLang($newlang); $outdesc_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["description"])) ? $object->multilangs[$outputlangs->defaultlang]["description"] : $object->description; $outlabel_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["label"])) ? $object->multilangs[$outputlangs->defaultlang]["label"] : $object->label; + } else { + $outdesc_trans = $object->description; + $outlabel_trans = $object->label; } } } From 88b570926f7ab66c829d979545a8b700445128bd Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 28 Oct 2020 15:38:31 +0000 Subject: [PATCH 008/184] Fixing style errors. --- htdocs/core/tpl/objectline_create.tpl.php | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index f1faf50e991..bc04e7b6614 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -678,13 +678,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) if (!empty($conf->global->PRODUIT_AUTOFILL_DESC)) { if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { ?> var proddesc = data.desc_trans; - var proddesc = data.desc; - console.log("Load desciption into text area : "+proddesc); - global->FCKEDITOR_ENABLE_DETAILS)) { ?> if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") { @@ -693,12 +693,12 @@ if (!empty($usemargins) && $user->rights->margins->creer) editor.setData(proddesc); } } - jQuery('#dp_desc').text(proddesc); - - }, 'json' @@ -873,12 +873,12 @@ if (!empty($usemargins) && $user->rights->margins->creer) global->PRODUIT_AUTOFILL_DESC)) { - ?> + ?> var description = $('option:selected', this).attr('data-description'); if (typeof description == 'undefined') { description = jQuery('#idprodfournprice').attr('data-description'); } console.log("Load desciption into text area : "+description); - global->FCKEDITOR_ENABLE_DETAILS)) { ?> if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") { @@ -887,10 +887,10 @@ if (!empty($usemargins) && $user->rights->margins->creer) editor.setData(description); } } - jQuery('#dp_desc').text(description); - } else if (jQuery('#idprodfournprice').length > 0) { @@ -904,10 +904,10 @@ if (!empty($usemargins) && $user->rights->margins->creer) editor.setData(''); } } - + jQuery('#dp_desc').text(''); - } From 11099132da9783cc3b4b0f7eacec8ee1e9d7f086 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Fri, 6 Nov 2020 00:45:30 +0100 Subject: [PATCH 009/184] New: add notification on ACTION_CREATE event --- htdocs/core/class/notify.class.php | 27 ++++++++++++++----- ..._50_modNotification_Notification.class.php | 3 ++- .../mysql/data/llx_c_action_trigger.sql | 2 +- htdocs/langs/en_US/other.lang | 2 ++ htdocs/langs/fr_FR/other.lang | 2 ++ 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 6547b98471a..fb0ce5a91f5 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -81,7 +81,8 @@ class Notify 'EXPENSE_REPORT_VALIDATE', 'EXPENSE_REPORT_APPROVE', 'HOLIDAY_VALIDATE', - 'HOLIDAY_APPROVE' + 'HOLIDAY_APPROVE', + 'ACTION_CREATE' ); @@ -502,12 +503,18 @@ class Notify $object_type = 'holiday'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated", $link); break; - case 'HOLIDAY_APPROVE': - $link = ''.$newref.''; - $dir_output = $conf->holiday->dir_output; - $object_type = 'holiday'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); - break; + case 'HOLIDAY_APPROVE': + $link = ''.$newref.''; + $dir_output = $conf->holiday->dir_output; + $object_type = 'holiday'; + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); + break; + case 'ACTION_CREATE': + $link = ''.$newref.''; + $dir_output = $conf->agenda->dir_output; + $object_type = 'action'; + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextActionAdded", $link); + break; } $ref = dol_sanitizeFileName($newref); $pdf_path = $dir_output."/".$ref."/".$ref.".pdf"; @@ -718,6 +725,12 @@ class Notify $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); break; + case 'ACTION_CREATE': + $link = ''.$newref.''; + $dir_output = $conf->agenda->dir_output; + $object_type = 'action'; + $mesg = $langs->transnoentitiesnoconv("EMailTextActionAdded", $link); + break; } $ref = dol_sanitizeFileName($newref); $pdf_path = $dir_output."/".$ref."/".$ref.".pdf"; diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index c5a4f450e42..a6078796478 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -46,7 +46,8 @@ class InterfaceNotification extends DolibarrTriggers 'EXPENSE_REPORT_VALIDATE', 'EXPENSE_REPORT_APPROVE', 'HOLIDAY_VALIDATE', - 'HOLIDAY_APPROVE' + 'HOLIDAY_APPROVE', + 'ACTION_CREATE' ); /** diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index eeca137dbc0..c72a8ab7f40 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -145,4 +145,4 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_MODIFY','Task modified','Executed when a project task is modified','project',151); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_DELETE','Task deleted','Executed when a project task is deleted','project',152); - +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ACTION_CREATE','Action added','Executed when an action is added to the agenda','agenda',700); diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 7495291cf3f..40f4f019793 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -78,6 +78,7 @@ Notify_EXPENSE_REPORT_VALIDATE=Expense report validated (approval required) Notify_EXPENSE_REPORT_APPROVE=Expense report approved Notify_HOLIDAY_VALIDATE=Leave request validated (approval required) Notify_HOLIDAY_APPROVE=Leave request approved +Notify_ACTION_CREATE=Added action to Agenda SeeModuleSetup=See setup of module %s NbOfAttachedFiles=Number of attached files/documents TotalSizeOfAttachedFiles=Total size of attached files/documents @@ -215,6 +216,7 @@ EMailTextExpenseReportValidated=Expense report %s has been validated. EMailTextExpenseReportApproved=Expense report %s has been approved. EMailTextHolidayValidated=Leave request %s has been validated. EMailTextHolidayApproved=Leave request %s has been approved. +EMailTextActionAdded=The action %s has been added to the Agenda. ImportedWithSet=Importation data set DolibarrNotification=Automatic notification ResizeDesc=Enter new width OR new height. Ratio will be kept during resizing... diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index 0a5abbfbf3a..5120fd52e67 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -78,6 +78,7 @@ Notify_EXPENSE_REPORT_VALIDATE=Note de frais validée (approbation requise) Notify_EXPENSE_REPORT_APPROVE=Note de frais approuvé Notify_HOLIDAY_VALIDATE=Demande de congé validée (approbation requise) Notify_HOLIDAY_APPROVE=Demande de congé approuvée +Notify_ACTION_CREATE=Ajout d'action à l'agenda SeeModuleSetup=Voir la configuration du module %s NbOfAttachedFiles=Nombre de fichiers/documents liés TotalSizeOfAttachedFiles=Taille totale fichiers/documents liés @@ -218,6 +219,7 @@ EMailTextExpenseReportValidated=La note de frais %s a été validée. EMailTextExpenseReportApproved=La note de frais %s a été approuvée. EMailTextHolidayValidated=La demande de congé %s a été validée. EMailTextHolidayApproved=La demande de congé %s a été approuvée. +EMailTextActionAdded=L'action %s a été ajoutée à l'Agenda. ImportedWithSet=Lot d'importation (Import key) DolibarrNotification=Notification automatique ResizeDesc=Entrer la nouvelle largeur OU la nouvelle hauteur. Le ratio d'aspect est conservé lors du redimensionnement… From f4566fe0f1fa8dace06466e45e65ccc690bb1ffd Mon Sep 17 00:00:00 2001 From: Bahfir Abbes Date: Mon, 9 Nov 2020 22:20:20 +0100 Subject: [PATCH 010/184] fix:link name --- htdocs/core/class/notify.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index fb0ce5a91f5..75d6a33c43b 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -510,7 +510,7 @@ class Notify $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); break; case 'ACTION_CREATE': - $link = ''.$newref.''; + $link = ''.$newref.''; $dir_output = $conf->agenda->dir_output; $object_type = 'action'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextActionAdded", $link); @@ -726,7 +726,7 @@ class Notify $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); break; case 'ACTION_CREATE': - $link = ''.$newref.''; + $link = ''.$newref.''; $dir_output = $conf->agenda->dir_output; $object_type = 'action'; $mesg = $langs->transnoentitiesnoconv("EMailTextActionAdded", $link); From 2c1d4049be08c850dd79a194993b2cf2cbfe2b80 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 10 Nov 2020 17:24:17 +0100 Subject: [PATCH 011/184] Enable list filtering on date and datetime extrafields --- htdocs/core/class/extrafields.class.php | 60 +++++++++++++++---- .../tpl/extrafields_list_search_input.tpl.php | 4 +- .../tpl/extrafields_list_search_param.tpl.php | 15 +++++ .../tpl/extrafields_list_search_sql.tpl.php | 10 +++- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 4b6f43bd06e..459a7b1820d 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -948,15 +948,15 @@ class ExtraFields * Return HTML string to put an input field into a page * Code very similar with showInputField of common object * - * @param string $key Key of attribute - * @param string $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value) - * @param string $moreparam To add more parametes on html input tag - * @param string $keysuffix Prefix string to add after name and id of field (can be used to avoid duplicate names) - * @param string $keyprefix Suffix string to add before name and id of field (can be used to avoid duplicate names) - * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) - * @param int $objectid Current object id - * @param string $extrafieldsobjectkey If defined (for example $object->table_element), use the new method to get extrafields data - * @param string $mode 1=Used for search filters + * @param string $key Key of attribute + * @param string|array $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value); for dates in filter mode, a range array('start'=>, 'end'=>) should be provided + * @param string $moreparam To add more parametes on html input tag + * @param string $keysuffix Prefix string to add after name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Suffix string to add before name and id of field (can be used to avoid duplicate names) + * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) + * @param int $objectid Current object id + * @param string $extrafieldsobjectkey If defined (for example $object->table_element), use the new method to get extrafields data + * @param string $mode 1=Used for search filters * @return string */ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '', $mode = 0) @@ -1069,8 +1069,23 @@ class ExtraFields // Do not show current date when field not required (see selectDate() method) if (!$required && $value == '') $value = '-1'; + if ($mode == 1) { + // search filter on a date extrafield shows two inputs to select a date range + $prefill = array( + 'start' => isset($value['start']) ? $value['start'] : '', + 'end' => isset($value['end']) ? $value['end'] : ''); + $out = '
' + . $langs->trans('From') . ' ' + . $form->selectDate($prefill['start'], $keyprefix . $key . $keysuffix . '_start', 0, 0, 1) + . '
' + . '
' + . $langs->trans('to') . ' ' + . $form->selectDate($prefill['end'], $keyprefix . $key . $keysuffix . '_end', 0, 0, 1) + . '
'; + } else { + $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1); + } // TODO Must also support $moreparam - $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1); } elseif (in_array($type, array('int', 'integer'))) { @@ -2162,9 +2177,28 @@ class ExtraFields if (in_array($key_type, array('date', 'datetime'))) { - if (!GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) continue; // Value was not provided, we should not set it. - // Clean parameters - $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), 0, GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int')); + $dateparamname_start = $keysuffix . 'options_' . $key . $keyprefix . '_start'; + $dateparamname_end = $keysuffix . 'options_' . $key . $keyprefix . '_end'; + if (GETPOSTISSET($dateparamname_start . 'year') && GETPOSTISSET($dateparamname_end . 'year')) { + // values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc. + $value_key = array( + 'start' => mktime( + 0, 0, 0, + GETPOST($dateparamname_start . 'month', 'int'), + GETPOST($dateparamname_start . 'day', 'int'), + GETPOST($dateparamname_start . 'year', 'int')), + 'end' => mktime( + 23, 59, 59, + GETPOST($dateparamname_end . 'month', 'int'), + GETPOST($dateparamname_end . 'day', 'int'), + GETPOST($dateparamname_end . 'year', 'int')) + ); + } elseif (GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) { + // Clean parameters + $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), 0, GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int')); + } else { + continue; // Value was not provided, we should not set it. + } } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) { diff --git a/htdocs/core/tpl/extrafields_list_search_input.tpl.php b/htdocs/core/tpl/extrafields_list_search_input.tpl.php index 6e1dae186b1..7fece2efd1d 100644 --- a/htdocs/core/tpl/extrafields_list_search_input.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_input.tpl.php @@ -36,8 +36,8 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } elseif (in_array($typeofextrafield, array('datetime', 'timestamp'))) { - // TODO - // Use showInputField in a particular manner to have input with a comparison operator, not input for a specific value date-hour-minutes + $morecss = ''; + echo $extrafields->showInputField($key, $search_array_options[$search_options_pattern.$tmpkey], '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1); } else { diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php index 6e6d6305106..009d05b30ee 100644 --- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php @@ -16,6 +16,21 @@ if (!empty($search_array_options) && is_array($search_array_options)) // $extraf { $crit = $val; $tmpkey = preg_replace('/'.$search_options_pattern.'/', '', $key); + if (is_array($val) && array_key_exists('start', $val) && array_key_exists('end', $val)) { + // date range from list filters is stored as array('start' => , 'end' => ) + // start date + $param .= '&' . $search_options_pattern.$tmpkey.'_startyear' . '=' . intval(dol_print_date($val['start'], '%Y')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startmonth' . '=' . intval(dol_print_date($val['start'], '%m')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startday' . '=' . intval(dol_print_date($val['start'], '%d')); + $param .= '&' . $search_options_pattern.$tmpkey.'_starthour' . '=' . intval(dol_print_date($val['start'], '%H')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startmin' . '=' . intval(dol_print_date($val['start'], '%M')); + // end date + $param .= '&' . $search_options_pattern.$tmpkey.'_endyear' . '=' . intval(dol_print_date($val['end'], '%Y')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endmonth' . '=' . intval(dol_print_date($val['end'], '%m')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endday' . '=' . intval(dol_print_date($val['end'], '%d')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endhour' . '=' . intval(dol_print_date($val['end'], '%H')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endmin' . '=' . intval(dol_print_date($val['end'], '%M')); + } if ($val != '') $param .= '&'.$search_options_pattern.$tmpkey.'='.urlencode($val); } } diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php index 03d487ee0c0..048ca24020a 100644 --- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -23,7 +23,15 @@ if (!empty($extrafieldsobjectkey) && !empty($search_array_options) && is_array($ if ($crit != '' && in_array($typ, array('date', 'datetime', 'timestamp'))) { - $sql .= " AND ".$extrafieldsobjectprefix.$tmpkey." = '".$db->idate($crit)."'"; + if (is_numeric($crit)) { + $sql .= " AND ".$extrafieldsobjectprefix.$tmpkey." = '".$db->idate($crit)."'"; + } elseif (is_array($crit)) { + $sql .= ' AND (' . $extrafieldsobjectprefix.$tmpkey + .' BETWEEN "' + . $db->idate($crit['start']) + . '" AND "' + . $db->idate($crit['end']) . '")'; + } } elseif (in_array($typ, array('boolean'))) { From a64c4b0cb5a74de2514279b311d4a7f765b80716 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 10 Nov 2020 17:29:03 +0100 Subject: [PATCH 012/184] support for $moreparam --- htdocs/core/class/extrafields.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 459a7b1820d..a188dafd885 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -950,7 +950,7 @@ class ExtraFields * * @param string $key Key of attribute * @param string|array $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value); for dates in filter mode, a range array('start'=>, 'end'=>) should be provided - * @param string $moreparam To add more parametes on html input tag + * @param string $moreparam To add more parameters on html input tag * @param string $keysuffix Prefix string to add after name and id of field (can be used to avoid duplicate names) * @param string $keyprefix Suffix string to add before name and id of field (can be used to avoid duplicate names) * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) @@ -1074,18 +1074,18 @@ class ExtraFields $prefill = array( 'start' => isset($value['start']) ? $value['start'] : '', 'end' => isset($value['end']) ? $value['end'] : ''); - $out = '
' + $out = '
' . $langs->trans('From') . ' ' . $form->selectDate($prefill['start'], $keyprefix . $key . $keysuffix . '_start', 0, 0, 1) . '
' . '
' . $langs->trans('to') . ' ' . $form->selectDate($prefill['end'], $keyprefix . $key . $keysuffix . '_end', 0, 0, 1) - . '
'; + . '
'; } else { + // TODO Must also support $moreparam $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1); } - // TODO Must also support $moreparam } elseif (in_array($type, array('int', 'integer'))) { From 952f398a609cc112e4f06748b54a24b80f6650f4 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 10 Nov 2020 23:50:42 +0100 Subject: [PATCH 013/184] Apply stickler CI recommendation to avoid concatenating string literals --- htdocs/core/class/extrafields.class.php | 3 +-- .../tpl/extrafields_list_search_param.tpl.php | 20 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index a188dafd885..b5d4852d128 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1077,8 +1077,7 @@ class ExtraFields $out = '
' . $langs->trans('From') . ' ' . $form->selectDate($prefill['start'], $keyprefix . $key . $keysuffix . '_start', 0, 0, 1) - . '
' - . '
' + . '
' . $langs->trans('to') . ' ' . $form->selectDate($prefill['end'], $keyprefix . $key . $keysuffix . '_end', 0, 0, 1) . '
'; diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php index 009d05b30ee..902d4df59ca 100644 --- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php @@ -19,17 +19,17 @@ if (!empty($search_array_options) && is_array($search_array_options)) // $extraf if (is_array($val) && array_key_exists('start', $val) && array_key_exists('end', $val)) { // date range from list filters is stored as array('start' => , 'end' => ) // start date - $param .= '&' . $search_options_pattern.$tmpkey.'_startyear' . '=' . intval(dol_print_date($val['start'], '%Y')); - $param .= '&' . $search_options_pattern.$tmpkey.'_startmonth' . '=' . intval(dol_print_date($val['start'], '%m')); - $param .= '&' . $search_options_pattern.$tmpkey.'_startday' . '=' . intval(dol_print_date($val['start'], '%d')); - $param .= '&' . $search_options_pattern.$tmpkey.'_starthour' . '=' . intval(dol_print_date($val['start'], '%H')); - $param .= '&' . $search_options_pattern.$tmpkey.'_startmin' . '=' . intval(dol_print_date($val['start'], '%M')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startyear=' . intval(dol_print_date($val['start'], '%Y')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startmonth=' . intval(dol_print_date($val['start'], '%m')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startday=' . intval(dol_print_date($val['start'], '%d')); + $param .= '&' . $search_options_pattern.$tmpkey.'_starthour=' . intval(dol_print_date($val['start'], '%H')); + $param .= '&' . $search_options_pattern.$tmpkey.'_startmin=' . intval(dol_print_date($val['start'], '%M')); // end date - $param .= '&' . $search_options_pattern.$tmpkey.'_endyear' . '=' . intval(dol_print_date($val['end'], '%Y')); - $param .= '&' . $search_options_pattern.$tmpkey.'_endmonth' . '=' . intval(dol_print_date($val['end'], '%m')); - $param .= '&' . $search_options_pattern.$tmpkey.'_endday' . '=' . intval(dol_print_date($val['end'], '%d')); - $param .= '&' . $search_options_pattern.$tmpkey.'_endhour' . '=' . intval(dol_print_date($val['end'], '%H')); - $param .= '&' . $search_options_pattern.$tmpkey.'_endmin' . '=' . intval(dol_print_date($val['end'], '%M')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endyear=' . intval(dol_print_date($val['end'], '%Y')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endmonth=' . intval(dol_print_date($val['end'], '%m')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endday=' . intval(dol_print_date($val['end'], '%d')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endhour=' . intval(dol_print_date($val['end'], '%H')); + $param .= '&' . $search_options_pattern.$tmpkey.'_endmin=' . intval(dol_print_date($val['end'], '%M')); } if ($val != '') $param .= '&'.$search_options_pattern.$tmpkey.'='.urlencode($val); } From 13f985d28085753683212eff42fd8e39cbcd2974 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 4 Dec 2020 04:13:42 +0100 Subject: [PATCH 014/184] NEW: Accountancy - Introduce "Level3" - Define account directly in thirdparty --- htdocs/accountancy/customer/index.php | 16 ++- htdocs/accountancy/customer/list.php | 38 ++++-- htdocs/accountancy/supplier/index.php | 14 +- htdocs/accountancy/supplier/list.php | 32 ++++- .../install/mysql/migration/13.0.0-14.0.0.sql | 36 +++++ htdocs/install/mysql/tables/llx_societe.sql | 3 + htdocs/langs/en_US/accountancy.lang | 1 + htdocs/societe/card.php | 124 +++++++++++++++++- htdocs/societe/class/societe.class.php | 101 +++++++++++++- 9 files changed, 338 insertions(+), 27 deletions(-) create mode 100644 htdocs/install/mysql/migration/13.0.0-14.0.0.sql diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 1a5098bda38..3634fba2e79 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2017 Alexandre Spangaro + * Copyright (C) 2013-2020 Alexandre Spangaro * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry * @@ -123,9 +123,9 @@ if ($action == 'validatehistory') { $sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.tva_tx as tva_tx_prod,"; $sql .= " p.accountancy_code_sell as code_sell, p.accountancy_code_sell_intra as code_sell_intra, p.accountancy_code_sell_export as code_sell_export,"; - $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; + $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,"; $sql .= " co.code as country_code, co.label as country_label,"; - $sql .= " s.tva_intra"; + $sql .= " s.tva_intra, s.accountancy_code_sell as company_code_sell"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; @@ -134,6 +134,7 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_sell = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON s.accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; @@ -153,7 +154,7 @@ if ($action == 'validatehistory') { $isBuyerInEEC = isInEEC($objp); - // Search suggested account for product/service (similar code exists in page list.php to make manual binding) + // Level 2: Search suggested account for product/service (similar code exists in page list.php to make manual binding) $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $objp->code_sell_p = $objp->code_sell; @@ -179,6 +180,13 @@ if ($action == 'validatehistory') { } } + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_sell)) { + $objp->code_sell_t = $objp->company_code_sell; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } + if ($objp->aarowid_suggest > 0) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet"; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index eb2743258d7..88464dcf95d 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -211,9 +211,9 @@ $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, $sql .= " p.accountancy_code_sell as code_sell, p.accountancy_code_sell_intra as code_sell_intra, p.accountancy_code_sell_export as code_sell_export,"; $sql .= " p.accountancy_code_buy as code_buy, p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export,"; $sql .= " p.tosell as status, p.tobuy as status_buy,"; -$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; +$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,"; $sql .= " co.code as country_code, co.label as country_label,"; -$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur"; +$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur, s.accountancy_code_sell as company_code_sell"; $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; @@ -225,6 +225,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_sell = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON s.accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; // Define begin binding date @@ -456,11 +457,12 @@ if ($result) { $facture_static->type = $objp->ftype; $code_sell_p_notset = ''; + $code_sell_t_notset = ''; $objp->aarowid_suggest = ''; // Will be set later $isBuyerInEEC = isInEEC($objp); - // Search suggested default account for product/service + // Level 1: Search suggested default account for product/service $suggestedaccountingaccountbydefaultfor = ''; if ($objp->type_l == 1) { if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) @@ -503,7 +505,7 @@ if ($result) { } if ($objp->code_sell_l == -1) $objp->code_sell_l = ''; - // Search suggested account for product/service (similar code exists in page index.php to make automatic binding) + // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $objp->code_sell_p = $objp->code_sell; @@ -529,6 +531,13 @@ if ($result) { } } + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_sell)) { + $objp->code_sell_t = $objp->company_code_sell; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } + // Manage Deposit if ($objp->description == "(DEPOSIT)") { $accountdeposittoventilated = new AccountingAccount($db); @@ -547,6 +556,7 @@ if ($result) { // $objp->code_sell_l is now default code of product/service // $objp->code_sell_p is now code of product/service + // $objp->code_sell_t is now code of thirdparty print ''; @@ -596,7 +606,7 @@ if ($result) { // Found accounts print ''; - $s = ''.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; + $s = '1. '.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; $shelp = ''; if ($suggestedaccountingaccountbydefaultfor == 'eec') $shelp .= $langs->trans("SaleEEC"); elseif ($suggestedaccountingaccountbydefaultfor == 'export') $shelp .= $langs->trans("SaleExport"); @@ -605,7 +615,7 @@ if ($result) { if ($objp->product_id > 0) { print '
'; - $s = ''.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; $shelp = ''; if ($suggestedaccountingaccountfor == 'eec') $shelp = $langs->trans("SaleEEC"); elseif ($suggestedaccountingaccountfor == 'eecwithvat') $shelp = $langs->trans("SaleEECWithVAT"); @@ -613,16 +623,23 @@ if ($result) { elseif ($suggestedaccountingaccountfor == 'export') $shelp = $langs->trans("SaleExport"); $s .= (empty($objp->code_sell_p) ? ''.$langs->trans("NotDefined").'' : length_accountg($objp->code_sell_p)); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); + } else { + print '
'; + $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $shelp = ''; + $s .= $langs->trans("NotDefined"); + print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); } + print '
'; + $s = '3. '.$langs->trans("DefaultForThirdparty").': '; + $shelp = ''; + $s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : ''.$langs->trans("NotDefined").''); + print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); print ''; // Suggested accounting account - // $objp->code_sell_l = default (it takes the country into consideration), $objp->code_sell_p is value for product (it takes the country into consideration too) print ''; $suggestedid = $objp->aarowid_suggest; - /*var_dump($suggestedid); - var_dump($objp->code_sell_p); - var_dump($objp->code_sell_l);*/ if (empty($suggestedid) && empty($objp->code_sell_p) && !empty($objp->code_sell_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { if (empty($accountingaccount_codetotid_cache[$objp->code_sell_l])) @@ -642,7 +659,6 @@ if ($result) { // Column with checkbox print ''; - //var_dump($objp->aarowid);var_dump($objp->aarowid_intra);var_dump($objp->aarowid_export);var_dump($objp->aarowid_suggest); $ischecked = $objp->aarowid_suggest; if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') $ischecked = 0; print ''; diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 0dbe09fa468..9dd097f3d0c 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -120,9 +120,9 @@ if ($action == 'validatehistory') { $sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type,"; $sql .= " p.accountancy_code_buy as code_buy, p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export, p.tva_tx as tva_tx_prod,"; - $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; + $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,"; $sql .= " co.code as country_code, co.label as country_label,"; - $sql .= " s.tva_intra"; + $sql .= " s.tva_intra, s.accountancy_code_buy as company_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; @@ -131,6 +131,7 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON s.accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; @@ -151,7 +152,7 @@ if ($action == 'validatehistory') { $isSellerInEEC = isInEEC($objp); - // Search suggested account for product/service + // Level 2: Search suggested account for product/service (similar code exists in page list.php to make manual binding) $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $objp->code_buy_p = $objp->code_buy; @@ -169,6 +170,13 @@ if ($action == 'validatehistory') { } } + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_buy)) { + $objp->code_buy_t = $objp->company_code_buy; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } + if ($objp->aarowid_suggest > 0) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det"; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index cbdecd2e85e..6f1f4c25a9f 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -215,9 +215,9 @@ $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, $sql .= " p.accountancy_code_sell as code_sell, p.accountancy_code_sell_intra as code_sell_intra, p.accountancy_code_sell_export as code_sell_export,"; $sql .= " p.accountancy_code_buy as code_buy, p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export,"; $sql .= " p.tosell as status, p.tobuy as status_buy,"; -$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; +$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,"; $sql .= " co.code as country_code, co.label as country_label,"; -$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur"; +$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur, s.accountancy_code_buy as company_code_buy"; $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; @@ -229,6 +229,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON s.accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; // Define begin binding date @@ -460,10 +461,12 @@ if ($result) { $facturefourn_static->label = $objp->invoice_label; $code_buy_p_notset = ''; + $code_buy_t_notset = ''; $objp->aarowid_suggest = ''; // Will be set later $isSellerInEEC = isInEEC($objp); + // Level 1: Search suggested default account for product/service $suggestedaccountingaccountbydefaultfor = ''; if ($objp->type_l == 1) { if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) @@ -494,7 +497,7 @@ if ($result) { } if ($objp->code_sell_l == -1) $objp->code_sell_l = ''; - // Search suggested account for product/service + // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) $suggestedaccountingaccountfor = ''; if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $objp->code_buy_p = $objp->code_buy; @@ -512,6 +515,13 @@ if ($result) { } } + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_buy)) { + $objp->code_buy_t = $objp->company_code_buy; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } + if (!empty($objp->code_buy_p)) { // Value was defined previously } else { @@ -521,6 +531,7 @@ if ($result) { // $objp->code_buy_l is now default code of product/service // $objp->code_buy_p is now code of product/service + // $objp->code_buy_t is now code of thirdparty print ''; @@ -576,7 +587,7 @@ if ($result) { // Found accounts print ''; - $s = ''.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; + $s = '1. '.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; $shelp = ''; if ($suggestedaccountingaccountbydefaultfor == 'eec') $shelp .= $langs->trans("SaleEEC"); elseif ($suggestedaccountingaccountbydefaultfor == 'export') $shelp .= $langs->trans("SaleExport"); @@ -585,13 +596,24 @@ if ($result) { if ($objp->product_id > 0) { print '
'; - $s = ''.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; $shelp = ''; if ($suggestedaccountingaccountfor == 'eec') $shelp = $langs->trans("SaleEEC"); elseif ($suggestedaccountingaccountfor == 'export') $shelp = $langs->trans("SaleExport"); $s .= (empty($objp->code_buy_p) ? ''.$langs->trans("NotDefined").'' : length_accountg($objp->code_buy_p)); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); + } else { + print '
'; + $s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; + $shelp = ''; + $s .= $langs->trans("NotDefined"); + print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); } + print '
'; + $s = '3. '.$langs->trans("DefaultForThirdparty").': '; + $shelp = ''; + $s .= ($objp->code_buy_t > 0 ? length_accountg($objp->code_buy_t) : ''.$langs->trans("NotDefined").''); + print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); print ''; // Suggested accounting account diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql new file mode 100644 index 00000000000..706ead91506 --- /dev/null +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -0,0 +1,36 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 14.0.0 or higher. +-- +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field); +-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): +-- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid; +-- -- VPGSQL8.2 ALTER TABLE llx_table ADD PRIMARY KEY (rowid); +-- -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN rowid SET DEFAULT nextval('llx_table_rowid_seq'); +-- -- VPGSQL8.2 SELECT setval('llx_table_rowid_seq', MAX(rowid)) FROM llx_table; +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. + + +-- Missing in v13 + +-- For v14 + +ALTER TABLE llx_societe ADD COLUMN accountancy_code_sell varchar(32) AFTER webservices_key; +ALTER TABLE llx_societe ADD COLUMN accountancy_code_buy varchar(32) AFTER accountancy_code_sell; diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index ea02b7be8ad..27503d82727 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -116,6 +116,9 @@ create table llx_societe webservices_url varchar(255), -- supplier webservice url webservices_key varchar(128), -- supplier webservice key + accountancy_code_sell varchar(32), -- Selling accountancy code + accountancy_code_buy varchar(32), -- Buying accountancy code + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- last modification date datec datetime, -- creation date fk_user_creat integer NULL, -- utilisateur qui a cree l'info diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 3211a0b62df..32f7949f3ef 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -16,6 +16,7 @@ ThisService=This service ThisProduct=This product DefaultForService=Default for service DefaultForProduct=Default for product +DefaultForThirdparty=Default for thirdparty CantSuggest=Can't suggest AccountancySetupDoneFromAccountancyMenu=Most setup of the accountancy is done from the menu %s ConfigAccountingExpert=Configuration of the module accounting (double entry) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 7d7dcbe86c3..c49d6115cc5 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -46,6 +46,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; if (!empty($conf->adherent->enabled)) require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; $langs->loadLangs(array("companies", "commercial", "bills", "banks", "users")); if (!empty($conf->adherent->enabled)) $langs->load("members"); @@ -476,6 +479,9 @@ if (empty($reshook)) $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); + $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + // Incoterms if (!empty($conf->incoterm->enabled)) { @@ -890,6 +896,7 @@ $form = new Form($db); $formfile = new FormFile($db); $formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db); if ($socid > 0 && empty($object->id)) { @@ -1030,6 +1037,9 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) $object->commercial_id = GETPOST('commercial_id', 'int'); $object->default_lang = GETPOST('default_lang'); + $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + $object->logo = (isset($_FILES['photo']) ?dol_sanitizeFileName($_FILES['photo']['name']) : ''); // Gestion du logo de la société @@ -1546,6 +1556,47 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ''."\n"; + // Accountancy codes + print ''; + + if (! empty($conf->accounting->enabled)) + { + // Accountancy_code_sell + print ''; + print ''; + + // Accountancy_code_buy + print ''; + print ''; + } + else // For external software + { + // Accountancy_code_sell + print ''; + print ''; + + // Accountancy_code_buy + print ''; + print ''; + } + print '
'.$langs->trans("ProductAccountancySellCode").''; + if($type == 0) { + $accountancy_code_sell = (GETPOST('accountancy_code_sell', 'alpha')?(GETPOST('accountancy_code_sell', 'alpha')):$conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT); + } else { + $accountancy_code_sell = (GETPOST('accountancy_code_sell', 'alpha')?(GETPOST('accountancy_code_sell', 'alpha')):$conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT); + } + print $formaccounting->select_account($accountancy_code_sell, 'accountancy_code_sell', 1, null, 1, 1, ''); + print '
'.$langs->trans("ProductAccountancyBuyCode").''; + if($type == 0) { + $accountancy_code_buy = (GETPOST('accountancy_code_buy', 'alpha')?(GETPOST('accountancy_code_buy', 'alpha')):$conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT); + } else { + $accountancy_code_buy = (GETPOST('accountancy_code_buy', 'alpha')?(GETPOST('accountancy_code_buy', 'alpha')):$conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT); + } + print $formaccounting->select_account($accountancy_code_buy, 'accountancy_code_buy', 1, null, 1, 1, ''); + print '
'.$langs->trans("ProductAccountancySellCode").''; + print '
'.$langs->trans("ProductAccountancyBuyCode").''; + print '
'; + print dol_get_fiche_end(); print '
'; @@ -1661,6 +1712,9 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); + $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + //Incoterms if (!empty($conf->incoterm->enabled)) { @@ -2188,10 +2242,42 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print $form->multiselectarray('commercial', $userlist, $arrayselected, null, null, null, null, "90%"); print ''; + print ''; + + print '
'; + + print ''; + + if (! empty($conf->accounting->enabled)) + { + // Accountancy_code_sell + print ''; + print ''; + + // Accountancy_code_buy + print ''; + print ''; + } + else // For external software + { + // Accountancy_code_sell + print ''; + print ''; + + // Accountancy_code_buy + print ''; + print ''; + } print '
'.$langs->trans("ProductAccountancySellCode").''; + print $formaccounting->select_account($object->accountancy_code_sell, 'accountancy_code_sell', 1, '', 1, 1); + print '
'.$langs->trans("ProductAccountancyBuyCode").''; + print $formaccounting->select_account($object->accountancy_code_buy, 'accountancy_code_buy', 1, '', 1, 1); + print '
'.$langs->trans("ProductAccountancySellCode").''; + print '
'.$langs->trans("ProductAccountancyBuyCode").''; + print '
'; print '
'; - print dol_get_fiche_end(); + print dol_get_fiche_end(); print '
'; print ''; @@ -2550,6 +2636,42 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ''; } + // Accountancy sell code + print ''; + print $langs->trans("ProductAccountancySellCode"); + print ''; + if (! empty($conf->accounting->enabled)) + { + if (! empty($object->accountancy_code_sell)) + { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $object->accountancy_code_sell, 1); + + print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + } + } else { + print $object->accountancy_code_sell; + } + print ''; + + // Accountancy buy code + print ''; + print $langs->trans("ProductAccountancyBuyCode"); + print ''; + if (! empty($conf->accounting->enabled)) + { + if (! empty($object->accountancy_code_buy)) + { + $accountingaccount2 = new AccountingAccount($db); + $accountingaccount2->fetch('', $object->accountancy_code_buy, 1); + + print $accountingaccount2->getNomUrl(0, 1, 1, '', 1); + } + } else { + print $object->accountancy_code_buy; + } + print ''; + // Other attributes $parameters = array('socid'=>$socid, 'colspan' => ' colspan="3"', 'colspanvalue' => '3'); include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 73c41aeb782..b3b3497dcf5 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -693,6 +693,15 @@ class Societe extends CommonObject */ public $logo_squarred_mini; + /** + * @var string Accountancy account for sales + */ + public $accountancy_code_sell; + + /** + * @var string Accountancy account for bought + */ + public $accountancy_code_buy; // Multicurrency /** @@ -792,6 +801,9 @@ class Societe extends CommonObject if (empty($this->fournisseur)) $this->fournisseur = 0; $this->import_key = trim($this->import_key); + $this->accountancy_code_buy = trim($this->accountancy_code_buy); + $this->accountancy_code_sell= trim($this->accountancy_code_sell); + if (!empty($this->multicurrency_code)) $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); if (empty($this->fk_multicurrency)) { @@ -817,8 +829,24 @@ class Societe extends CommonObject { $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe (nom, name_alias, entity, datec, fk_user_creat, canvas, status, ref_ext, fk_stcomm, fk_incoterms, location_incoterms ,import_key, fk_multicurrency, multicurrency_code)"; - $sql .= " VALUES ('".$this->db->escape($this->name)."', '".$this->db->escape($this->name_alias)."', ".$this->db->escape($this->entity).", '".$this->db->idate($now)."'"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe ("; + $sql .= "nom"; + $sql .= ", name_alias"; + $sql .= ", entity"; + $sql .= ", datec"; + $sql .= ", fk_user_creat"; + $sql .= ", canvas"; + $sql .= ", status"; + $sql .= ", ref_ext"; + $sql .= ", fk_stcomm"; + $sql .= ", fk_incoterms"; + $sql .= ", location_incoterms"; + $sql .= ", import_key"; + $sql .= ", fk_multicurrency"; + $sql .= ", multicurrency_code"; + $sql .= ", accountancy_code_buy"; + $sql .= ", accountancy_code_sell"; + $sql .= ") VALUES ('".$this->db->escape($this->name)."', '".$this->db->escape($this->name_alias)."', ".$this->db->escape($this->entity).", '".$this->db->idate($now)."'"; $sql .= ", ".(!empty($user->id) ? ((int) $user->id) : "null"); $sql .= ", ".(!empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'" : "null"); $sql .= ", ".$this->status; @@ -828,7 +856,10 @@ class Societe extends CommonObject $sql .= ", '".$this->db->escape($this->location_incoterms)."'"; $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null"); $sql .= ", ".(int) $this->fk_multicurrency; - $sql .= ", '".$this->db->escape($this->multicurrency_code)."')"; + $sql .= ", '".$this->db->escape($this->multicurrency_code)."'"; + $sql .= ", '".$this->db->escape($this->accountancy_code_buy)."'"; + $sql .= ", '".$this->db->escape($this->accountancy_code_sell)."'"; + $sql .= ")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); $result = $this->db->query($sql); @@ -1196,6 +1227,9 @@ class Societe extends CommonObject $this->webservices_url = $this->webservices_url ?clean_url($this->webservices_url, 0) : ''; $this->webservices_key = trim($this->webservices_key); + $this->accountancy_code_buy = trim($this->accountancy_code_buy); + $this->accountancy_code_sell= trim($this->accountancy_code_sell); + //Incoterms $this->fk_incoterms = (int) $this->fk_incoterms; $this->location_incoterms = trim($this->location_incoterms); @@ -1320,6 +1354,9 @@ class Societe extends CommonObject $sql .= ",supplier_order_min_amount= ".($this->supplier_order_min_amount != '' ? $this->supplier_order_min_amount : 'null'); $sql .= ",fk_prospectlevel='".$this->db->escape($this->fk_prospectlevel)."'"; + $sql.= ", accountancy_code_buy = '" . $this->db->escape($this->accountancy_code_buy)."'"; + $sql.= ", accountancy_code_sell= '" . $this->db->escape($this->accountancy_code_sell)."'"; + $sql .= ",webservices_url = ".(!empty($this->webservices_url) ? "'".$this->db->escape($this->webservices_url)."'" : "null"); $sql .= ",webservices_key = ".(!empty($this->webservices_key) ? "'".$this->db->escape($this->webservices_key)."'" : "null"); @@ -1505,6 +1542,7 @@ class Societe extends CommonObject $sql .= ', s.fk_effectif as effectif_id'; $sql .= ', s.fk_forme_juridique as forme_juridique_code'; $sql .= ', s.webservices_url, s.webservices_key'; + $sql .= ', s.accountancy_code_buy, s.accountancy_code_sell'; $sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode'; $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.remise_supplier, s.mode_reglement, s.cond_reglement, s.transport_mode'; $sql .= ', s.fk_account, s.tva_assuj'; @@ -1668,6 +1706,9 @@ class Societe extends CommonObject $this->webservices_url = $obj->webservices_url; $this->webservices_key = $obj->webservices_key; + $this->accountancy_code_buy = $obj->accountancy_code_buy; + $this->accountancy_code_sell = $obj->accountancy_code_sell; + $this->outstanding_limit = $obj->outstanding_limit; $this->order_min_amount = $obj->order_min_amount; $this->supplier_order_min_amount = $obj->supplier_order_min_amount; @@ -4403,4 +4444,58 @@ class Societe extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Sets an accountancy code for a thirdparty. + * Also calls COMPANY_MODIFY trigger when modified + * + * @param string $type It can be only 'buy' or 'sell' + * @param string $value Accountancy code + * @return int <0 KO >0 OK + */ + public function setAccountancyCode($type, $value) + { + global $user, $langs, $conf; + + $this->db->begin(); + + if ($type == 'buy') { + $field = 'accountancy_code_buy'; + } elseif ($type == 'sell') { + $field = 'accountancy_code_sell'; + } else { + return -1; + } + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET "; + $sql.= "$field = '".$this->db->escape($value)."'"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::".__FUNCTION__." sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + + if ($resql) { + // Call triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('COMPANY_MODIFY', $this, $user, $langs, $conf); + if ($result < 0) { + $this->errors=$interface->errors; + $this->db->rollback(); + return -1; + } + // End call triggers + + $this->$field = $value; + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } } From d6ac26dd8595d256b31ae5a599b2e6156975ae66 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 4 Dec 2020 03:23:48 +0000 Subject: [PATCH 015/184] Fixing style errors. --- htdocs/societe/card.php | 4 ++-- htdocs/societe/class/societe.class.php | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index c49d6115cc5..0e64117d632 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1564,7 +1564,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // Accountancy_code_sell print ''.$langs->trans("ProductAccountancySellCode").''; print ''; - if($type == 0) { + if ($type == 0) { $accountancy_code_sell = (GETPOST('accountancy_code_sell', 'alpha')?(GETPOST('accountancy_code_sell', 'alpha')):$conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT); } else { $accountancy_code_sell = (GETPOST('accountancy_code_sell', 'alpha')?(GETPOST('accountancy_code_sell', 'alpha')):$conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT); @@ -1575,7 +1575,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // Accountancy_code_buy print ''.$langs->trans("ProductAccountancyBuyCode").''; print ''; - if($type == 0) { + if ($type == 0) { $accountancy_code_buy = (GETPOST('accountancy_code_buy', 'alpha')?(GETPOST('accountancy_code_buy', 'alpha')):$conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT); } else { $accountancy_code_buy = (GETPOST('accountancy_code_buy', 'alpha')?(GETPOST('accountancy_code_buy', 'alpha')):$conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index b3b3497dcf5..c8fc2f58e74 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -4491,8 +4491,7 @@ class Societe extends CommonObject $this->db->commit(); return 1; } - else - { + else { $this->error=$this->db->lasterror(); $this->db->rollback(); return -1; From 54fad02936cfc37624128117a54c22d9e48bd7db Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 8 Dec 2020 13:55:51 +0100 Subject: [PATCH 016/184] Fix PR --- htdocs/accountancy/customer/list.php | 2 +- htdocs/accountancy/supplier/list.php | 2 +- htdocs/langs/en_US/accountancy.lang | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 88464dcf95d..cb47e436cbd 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -631,7 +631,7 @@ if ($result) { print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); } print '
'; - $s = '3. '.$langs->trans("DefaultForThirdparty").': '; + $s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': '; $shelp = ''; $s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : ''.$langs->trans("NotDefined").''); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 6f1f4c25a9f..919130e80d3 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -610,7 +610,7 @@ if ($result) { print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); } print '
'; - $s = '3. '.$langs->trans("DefaultForThirdparty").': '; + $s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': '; $shelp = ''; $s .= ($objp->code_buy_t > 0 ? length_accountg($objp->code_buy_t) : ''.$langs->trans("NotDefined").''); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 32f7949f3ef..d0fbc1644b3 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -16,7 +16,8 @@ ThisService=This service ThisProduct=This product DefaultForService=Default for service DefaultForProduct=Default for product -DefaultForThirdparty=Default for thirdparty +ProductForThisThirdparty=Product for this thirdparty +ServiceForThisThirdparty=Service for this thirdparty CantSuggest=Can't suggest AccountancySetupDoneFromAccountancyMenu=Most setup of the accountancy is done from the menu %s ConfigAccountingExpert=Configuration of the module accounting (double entry) From 64fa2120b2e6e577e66fd1e93e5035a61c510af7 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 15 Dec 2020 08:40:14 +0100 Subject: [PATCH 017/184] FIX: Link to subaccount ledger --- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 +- htdocs/langs/en_US/accountancy.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 18661f8a887..cd15eea52be 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -380,7 +380,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); - $newcardbutton .= dolGetButtonTitle($langs->trans('VueByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('VueBySubAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= '   '; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 7b406af0c79..14bebea22df 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -50,6 +50,7 @@ CountriesExceptMe=All countries except %s AccountantFiles=Export source documents ExportAccountingSourceDocHelp=With this tool, you can export the source events (list and PDFs) that were used to generate your accountancy. To export your journals, use the menu entry %s - %s. VueByAccountAccounting=View by accounting account +VueBySubAccountAccounting=View by accounting subaccount MainAccountForCustomersNotDefined=Main accounting account for customers not defined in setup MainAccountForSuppliersNotDefined=Main accounting account for vendors not defined in setup From 31e5709e0bd4545f534340f16c2b8c001fe16e66 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 15 Dec 2020 09:32:54 +0100 Subject: [PATCH 018/184] Revert "FIX: Link to subaccount ledger" This reverts commit 64fa2120b2e6e577e66fd1e93e5035a61c510af7. --- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 +- htdocs/langs/en_US/accountancy.lang | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index cd15eea52be..18661f8a887 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -380,7 +380,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); - $newcardbutton .= dolGetButtonTitle($langs->trans('VueBySubAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('VueByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= '   '; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 14bebea22df..7b406af0c79 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -50,7 +50,6 @@ CountriesExceptMe=All countries except %s AccountantFiles=Export source documents ExportAccountingSourceDocHelp=With this tool, you can export the source events (list and PDFs) that were used to generate your accountancy. To export your journals, use the menu entry %s - %s. VueByAccountAccounting=View by accounting account -VueBySubAccountAccounting=View by accounting subaccount MainAccountForCustomersNotDefined=Main accounting account for customers not defined in setup MainAccountForSuppliersNotDefined=Main accounting account for vendors not defined in setup From 64a62bf2c2ac0d5747aa14f012e5098d853599b8 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 22 Dec 2020 09:37:30 +0100 Subject: [PATCH 019/184] FIX (PR #15346 comment) use dol_mktime, not mktime --- htdocs/core/class/extrafields.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index b5d4852d128..1144cf5c682 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -2181,12 +2181,12 @@ class ExtraFields if (GETPOSTISSET($dateparamname_start . 'year') && GETPOSTISSET($dateparamname_end . 'year')) { // values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc. $value_key = array( - 'start' => mktime( + 'start' => dol_mktime( 0, 0, 0, GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int')), - 'end' => mktime( + 'end' => dol_mktime( 23, 59, 59, GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), From fefc9040ab56747c450ce90de70a0360e1090fe6 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 22 Dec 2020 12:52:01 +0100 Subject: [PATCH 020/184] NEW : Display extrafields (for lines/det into line tr instead of ugly other tr --- composer.json | 2 +- htdocs/core/class/commonobjectline.class.php | 251 +++++++++++++++++++ htdocs/core/class/extrafields.class.php | 37 ++- htdocs/core/tpl/objectline_create.tpl.php | 7 +- htdocs/core/tpl/objectline_edit.tpl.php | 14 +- htdocs/core/tpl/objectline_view.tpl.php | 13 +- 6 files changed, 293 insertions(+), 31 deletions(-) diff --git a/composer.json b/composer.json index bd81e101cfc..a943fbe0aa3 100644 --- a/composer.json +++ b/composer.json @@ -59,4 +59,4 @@ "ext-zip" : "ODT, Excel and file compression support", "ext-xml" : "Excel support" } -} \ No newline at end of file +} diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index 0d4cfbe4f34..806e0f2a663 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -100,4 +100,255 @@ abstract class CommonObjectLine extends CommonObject // Currently we need function at end of file CommonObject for all object lines. Should find a way to avoid duplicate code. // For the moment we use the extends on CommonObject until PHP min is 5.4 so use Traits. + + /** + * Function to show lines of extrafields with output datas. + * This function is responsible to output the and according to correct number of columns received into $params['colspan'] + * + * @param Extrafields $extrafields Extrafield Object + * @param string $mode Show output ('view') or input ('create' or 'edit') for extrafield + * @param array $params Optional parameters. Example: array('style'=>'class="oddeven"', 'colspan'=>$colspan) + * @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names) + * @param string $onetrtd All fields in same tr td. Used by objectline_create.tpl.php for example. + * @return string + */ + public function showOptionals($extrafields, $mode = 'view', $params = null, $keysuffix = '', $keyprefix = '', $onetrtd = 0) + { + global $db, $conf, $langs, $action, $form, $hookmanager; + + if (!is_object($form)) $form = new Form($db); + + $out = ''; + + $parameters = array(); + $reshook = $hookmanager->executeHooks('showOptionals', $parameters, $this, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) + { + if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0) + { + $out .= "\n"; + $out .= ' '; + $out .= "\n"; + + $extrafields_collapse_num = ''; + $e = 0; + foreach ($extrafields->attributes[$this->table_element]['label'] as $key=>$label) + { + // Show only the key field in params + if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) continue; + + // Test on 'enabled' ('enabled' is different than 'list' = 'visibility') + $enabled = 1; + if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key])) + { + $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1); + } + if (empty($enabled)) continue; + + $visibility = 1; + if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key])) + { + $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1); + } + + $perms = 1; + if ($perms && isset($extrafields->attributes[$this->table_element]['perms'][$key])) + { + $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1); + } + + if (($mode == 'create') && abs($visibility) != 1 && abs($visibility) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list + elseif (($mode == 'edit') && abs($visibility) != 1 && abs($visibility) != 3 && abs($visibility) != 4) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation + elseif ($mode == 'view' && empty($visibility)) continue; + if (empty($perms)) continue; + // Load language if required + if (!empty($extrafields->attributes[$this->table_element]['langfile'][$key])) { + $langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]); + } + + switch ($mode) { + case "view": + $value = $this->array_options["options_".$key.$keysuffix]; // Value may be clean or formated later + break; + case "create": + case "edit": + // We get the value of property found with GETPOST so it takes into account: + // default values overwrite, restore back to list link, ... (but not 'default value in database' of field) + $check = 'alphanohtml'; + if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text'))) { + $check = 'restricthtml'; + } + $getposttemp = GETPOST($keyprefix.'options_'.$key.$keysuffix, $check, 3); // GETPOST can get value from GET, POST or setup of default values overwrite. + // GETPOST("options_" . $key) can be 'abc' or array(0=>'abc') + if (is_array($getposttemp) || $getposttemp != '' || GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) + { + if (is_array($getposttemp)) { + // $getposttemp is an array but following code expects a comma separated string + $value = implode(",", $getposttemp); + } else { + $value = $getposttemp; + } + } else { + $value = $this->array_options["options_".$key]; // No GET, no POST, no default value, so we take value of object. + } + //var_dump($keyprefix.' - '.$key.' - '.$keysuffix.' - '.$keyprefix.'options_'.$key.$keysuffix.' - '.$this->array_options["options_".$key.$keysuffix].' - '.$getposttemp.' - '.$value); + break; + } + + if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate') + { + $extrafields_collapse_num = ''; + $extrafield_param = $extrafields->attributes[$this->table_element]['param'][$key]; + if (!empty($extrafield_param) && is_array($extrafield_param)) { + $extrafield_param_list = array_keys($extrafield_param['options']); + + if (count($extrafield_param_list) > 0) { + $extrafield_collapse_display_value = intval($extrafield_param_list[0]); + + if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { + $extrafields_collapse_num = $extrafields->attributes[$this->table_element]['pos'][$key]; + } + } + } + + $out .= $extrafields->showSeparator($key, $this, 0, 'line'); + } else { + $class = (!empty($extrafields->attributes[$this->table_element]['hidden'][$key]) ? 'hideobject ' : ''); + $csstyle = ''; + if (is_array($params) && count($params) > 0) { + if (array_key_exists('class', $params)) { + $class .= $params['class'].' '; + } + if (array_key_exists('style', $params)) { + $csstyle = $params['style']; + } + } + + // add html5 elements + $domData = ' data-element="extrafield"'; + $domData .= ' data-targetelement="'.$this->element.'"'; + $domData .= ' data-targetid="'.$this->id.'"'; + + $html_id = (empty($this->id) ? '' : 'extrarow-'.$this->element.'_'.$key.'_'.$this->id); + + // Convert date into timestamp format (value in memory must be a timestamp) + if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime'))) + { + $datenotinstring = $this->array_options['options_'.$key]; + if (!is_numeric($this->array_options['options_'.$key])) // For backward compatibility + { + $datenotinstring = $this->db->jdate($datenotinstring); + } + $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(GETPOST($keyprefix.'options_'.$key.$keysuffix."hour", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."min", 'int', 3), 0, GETPOST($keyprefix.'options_'.$key.$keysuffix."month", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year", 'int', 3)) : $datenotinstring; + } + // Convert float submited string into real php numeric (value in memory must be a php numeric) + if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('price', 'double'))) + { + $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? price2num($value) : $this->array_options['options_'.$key]; + } + + // HTML, text, select, integer and varchar: take into account default value in database if in create mode + if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'varchar', 'select', 'int'))) + { + if ($action == 'create') $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? $value : $extrafields->attributes[$this->table_element]['default'][$key]; + } + + $labeltoshow = $langs->trans($label); + $helptoshow = $langs->trans($extrafields->attributes[$this->table_element]['help'][$key]); + + $out .= '
'; + $out .= '
attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow); + else $out .= $labeltoshow; + if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' *'; + } else { + if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired'; + $out .= '">'; + if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow); + else $out .= $labeltoshow; + } + $out .= '
'; + + $html_id = !empty($this->id) ? $this->element.'_extras_'.$key.'_'.$this->id : ''; + + $out .= '
'; + + switch ($mode) { + case "view": + $out .= $extrafields->showOutputField($key, $value); + break; + case "create": + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element); + break; + case "edit": + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element); + break; + } + + $out .= '
'; + + /*for($ii = 0; $ii < ($colspan - 1); $ii++) + { + $out .=''; + }*/ + + if (!empty($conf->global->MAIN_EXTRAFIELDS_USE_TWO_COLUMS) && (($e % 2) == 1)) $out .= '
'; + else $out .= '
'; + $e++; + } + } + $out .= "\n"; + // Add code to manage list depending on others + if (!empty($conf->use_javascript_ajax)) { + $out .= ' + '."\n"; + } + + $out .= ' '."\n"; + } + } + + $out .= $hookmanager->resPrint; + + return $out; + } } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index d041aba45f4..e6a11b17c67 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1912,15 +1912,28 @@ class ExtraFields * @param string $key Key of attribute * @param string $object Object * @param int $colspan Value of colspan to use (it must includes the first column with title) + * @param string $typeform "card" for from display, "line" for docuement line display (exstraiedls on propal line, order line, etc...) * @return string HTML code with line for separator */ - public function showSeparator($key, $object, $colspan = 2) + public function showSeparator($key, $object, $colspan = 2, $typeform='card') { global $langs; - $out = ''; + if ($typeform=='card') { + $tagtype='tr'; + $tagtype_dyn='td'; + }elseif ($typeform=='line') { + $tagtype='div'; + $tagtype_dyn='span'; + } + + $out = '<'.$tagtype.' id="trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'" class="trextrafieldseparator trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'">'; + $out .= '<'.$tagtype_dyn.' '.(!empty($colspan)?'colspan="' . $colspan . '"':'').'>'; + $out .=''; $out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]); - $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; $extrafield_param = $this->attributes[$object->table_element]['param'][$key]; if (!empty($extrafield_param) && is_array($extrafield_param)) { @@ -1930,27 +1943,27 @@ class ExtraFields $extrafield_collapse_display_value = intval($extrafield_param_list[0]); if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { // Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup. - $collapse_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key]) || GETPOST('ignorecollapsesetup', 'int')) ? ($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key] ? true : false) : ($extrafield_collapse_display_value == 2 ? false : true)); - $extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key]; + $collapse_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'')]) || GETPOST('ignorecollapsesetup', 'int')) ? ($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'')] ? true : false) : ($extrafield_collapse_display_value == 2 ? false : true)); + $extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:''); $out .= ''; $out .= ''."\n"; - } - - $out .= ' '."\n"; - } - } - - $out .= $hookmanager->resPrint; - - return $out; - } } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 0e0f5acd4a4..0800a568d84 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1902,19 +1902,20 @@ class ExtraFields * @param string $key Key of attribute * @param string $object Object * @param int $colspan Value of colspan to use (it must includes the first column with title) - * @param string $typeform "card" for from display, "line" for docuement line display (exstraiedls on propal line, order line, etc...) + * @param string $display_type "card" for form display, "line" for document line display (extrafields on propal line, order line, etc...) * @return string HTML code with line for separator */ - public function showSeparator($key, $object, $colspan = 2, $typeform='card') + public function showSeparator($key, $object, $colspan = 2, $display_type = 'card') { global $langs; - if ($typeform=='card') { + if ($display_type=='card') { $tagtype='tr'; $tagtype_dyn='td'; - }elseif ($typeform=='line') { + }elseif ($display_type=='line') { $tagtype='div'; $tagtype_dyn='span'; + $colspan=0; } $out = '<'.$tagtype.' id="trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'" class="trextrafieldseparator trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'">'; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index cced0915681..dcc2257f2c5 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -321,7 +321,7 @@ if ($nolinesbefore) { } if (is_object($objectline)) { print '
'; - print $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1); + print $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1, 'line'); print '
'; } echo ''; diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 3115e4e2f0c..a174c82544d 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -129,7 +129,7 @@ $coldisplay++; if (!empty($extrafields)) { print '
'; - print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited'), '', '', 1); + print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited'), '', '', 1, 'line'); print '
'; } diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 337970412de..e4ca44438f7 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -162,7 +162,7 @@ if (($line->info_bits & 2) == 2) { if (!empty($extrafields)) { print '
'; - print $line->showOptionals($extrafields, 'view', array(), '', '', 1); + print $line->showOptionals($extrafields, 'view', array(), '', '', 1, 'line'); print '
'; } } From ff25003025626eaa74514c42ff52aea9bc3d22e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 5 Jan 2021 08:59:46 +0100 Subject: [PATCH 042/184] fix unknown variable --- .../bank/class/api_bankaccounts.class.php | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 9ab02d8b18a..be37ec23403 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -81,10 +81,8 @@ class BankAccounts extends DolibarrApi $sql .= " AND c.fk_categorie = ".$this->db->escape($category)." AND c.fk_account = t.rowid "; } // Add sql filters - if ($sqlfilters) - { - if (!DolibarrApi::_checkFilters($sqlfilters)) - { + if ($sqlfilters) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; @@ -93,8 +91,7 @@ class BankAccounts extends DolibarrApi $sql .= $this->db->order($sortfield, $sortorder); if ($limit) { - if ($page < 0) - { + if ($page < 0) { $page = 0; } $offset = $limit * $page; @@ -222,12 +219,10 @@ class BankAccounts extends DolibarrApi throw new RestException(404, 'The BankAccount for bankaccount_to_id provided does not exist.'); } - if ($accountto->currency_code == $accountfrom->currency_code) - { + if ($accountto->currency_code == $accountfrom->currency_code) { $amount_to = $amount; } else { - if (!$amount_to || empty($amount_to)) - { + if (!$amount_to || empty($amount_to)) { throw new RestException(422, 'You must provide amount_to value since bankaccount_from and bankaccount_to does not share the same currency.'); } } @@ -244,8 +239,7 @@ class BankAccounts extends DolibarrApi $typefrom = 'PRE'; $typeto = 'VIR'; - if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH) - { + if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH) { // This is transfer of change $typefrom = 'LIQ'; $typeto = 'LIQ'; @@ -291,8 +285,7 @@ class BankAccounts extends DolibarrApi $error++; } - if (!$error) - { + if (!$error) { $this->db->commit(); return array( @@ -327,12 +320,13 @@ class BankAccounts extends DolibarrApi } foreach ($request_data as $field => $value) { - if ($field == 'id') continue; + if ($field == 'id') { + continue; + } $account->$field = $value; } - if ($account->update(DolibarrApiAccess::$user) > 0) - { + if ($account->update(DolibarrApiAccess::$user) > 0) { return $this->get($id); } else { throw new RestException(500, $account->error); @@ -380,8 +374,9 @@ class BankAccounts extends DolibarrApi { $account = array(); foreach (BankAccounts::$FIELDS as $field) { - if (!isset($data[$field])) + if (!isset($data[$field])) { throw new RestException(400, "$field field missing"); + } $account[$field] = $data[$field]; } return $account; @@ -433,10 +428,8 @@ class BankAccounts extends DolibarrApi $sql .= " WHERE fk_account = ".$id; // Add sql filters - if ($sqlfilters) - { - if (!DolibarrApi::_checkFilters($sqlfilters)) - { + if ($sqlfilters) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; @@ -457,7 +450,7 @@ class BankAccounts extends DolibarrApi } } } else { - throw new RestException(503, 'Error when retrieving list of account lines: '.$accountLine->error); + throw new RestException(503, 'Error when retrieving list of account lines: '.$this->db->lasterror()); } return $list; @@ -476,8 +469,8 @@ class BankAccounts extends DolibarrApi * @param string $cheque_writer Name of cheque writer {@from body} * @param string $cheque_bank Bank of cheque writer {@from body} * @param string $accountancycode Accountancy code {@from body} - * @param int $datev Payment date value (timestamp) {@from body} {@type timestamp} - * @param string $num_releve Bank statement numero {@from body} + * @param int $datev Payment date value (timestamp) {@from body} {@type timestamp} + * @param string $num_releve Bank statement numero {@from body} * @return int ID of line * * @url POST {id}/lines @@ -502,8 +495,11 @@ class BankAccounts extends DolibarrApi $cheque_number, $category, DolibarrApiAccess::$user, - $cheque_writer, $cheque_bank, $accountancycode, - $datev, $num_releve + $cheque_writer, + $cheque_bank, + $accountancycode, + $datev, + $num_releve ); if ($result < 0) { throw new RestException(503, 'Error when adding line to account: '.$account->error); From f845adf3431cde836d9238bf1ce1c866451d9b7c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 5 Jan 2021 09:57:35 +0100 Subject: [PATCH 043/184] FIX use GETPOST before --- htdocs/admin/accountant.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/admin/accountant.php b/htdocs/admin/accountant.php index 3647c10f5ea..8f20ab43c84 100644 --- a/htdocs/admin/accountant.php +++ b/htdocs/admin/accountant.php @@ -114,53 +114,53 @@ print ''.$langs->trans( // Name print ''; -print 'global->MAIN_OPTIMIZEFORTEXTBROWSER) ? '' : ' autofocus="autofocus"').'>'."\n"; +print 'global->MAIN_OPTIMIZEFORTEXTBROWSER) ? '' : ' autofocus="autofocus"').'>'."\n"; // Address print ''; -print ''."\n"; +print ''."\n"; print ''; -print ''."\n"; +print ''."\n"; print ''; -print ''."\n"; +print ''."\n"; // Country print ''; print img_picto('', 'globe-americas', 'class="paddingrightonly"'); -print $form->select_country((!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : GETPOST('country_id', 'int')), 'country_id'); +print $form->select_country((GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : '')), 'country_id'); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); print ''."\n"; print ''; -$formcompany->select_departement((!empty($conf->global->MAIN_INFO_ACCOUNTANT_STATE) ? $conf->global->MAIN_INFO_ACCOUNTANT_STATE : GETPOST('state_id', 'alpha')), (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : GETPOST('country_id', 'int')), 'state_id'); +$formcompany->select_departement((GETPOSTISSET('state_id') ? GETPOST('state_id', 'alpha') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_STATE) ? $conf->global->MAIN_INFO_ACCOUNTANT_STATE : '')), (GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : '')), 'state_id'); print ''."\n"; print ''; print img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; print ''; print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; print ''; print img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Web print ''; print img_picto('', 'globe', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Code print ''; -print ''."\n"; +print ''."\n"; // Note print ''; From 889d73d8e3a8c5aeabb57754c60bb8b21e91ce93 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 5 Jan 2021 10:16:24 +0100 Subject: [PATCH 044/184] FIX avoid php8 warning --- htdocs/admin/company.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index fd3f7505778..2801951974e 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -393,18 +393,18 @@ print ''.$langs->trans( // Name print ''; -print 'global->MAIN_INFO_SOCIETE_NOM) ? ' autofocus="autofocus"' : '').'>'."\n"; +print 'global->MAIN_INFO_SOCIETE_NOM) ? ' autofocus="autofocus"' : '').'>'."\n"; // Address print ''; -print ''."\n"; +print ''."\n"; // Zip print ''; -print ''."\n"; +print ''."\n"; print ''; -print ''."\n"; +print ''."\n"; // Country print ''; @@ -431,25 +431,25 @@ print ''."\n"; // Phone print ''; print img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Fax print ''; print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Email print ''; print img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Web print ''; print img_picto('', 'globe', '', false, 0, 0, '', 'paddingright'); -print ''; +print ''; print ''."\n"; // Barcode @@ -457,7 +457,7 @@ if (!empty($conf->barcode->enabled)) { print ''; print ''; print ''; - print ''; + print ''; print ''; } @@ -549,7 +549,7 @@ $langs->load("companies"); // Managing Director(s) print ''; -print ''; +print ''; // GDPR contact print ''; @@ -559,7 +559,7 @@ print ''; -print ''; +print ''; // Juridical Status print ''; From 4b45c5e72365aa61eab5ab4487fd0df2d5f25bac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Jan 2021 12:29:13 +0100 Subject: [PATCH 045/184] Trans --- htdocs/core/lib/project.lib.php | 8 +++++--- htdocs/langs/en_US/projects.lang | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 74e624ca7cb..3c8a79a9249 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2526,13 +2526,15 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '') if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { $badgeClass .= 'badge-danger'; - if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; + if (empty($tooltip)) { + $tooltip = $task->progress.'% < '.$langs->trans("TimeConsumed").' '.$progressCalculated.'%'; + } } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% $badgeClass .= 'badge-warning'; - if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; + if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("TimeConsumed").' '.$progressCalculated.'%'; } else { $badgeClass .= 'badge-success'; - if (empty($tooltip)) $tooltip = $task->progress.'% >= '.$langs->trans("Expected").' '.$progressCalculated.'%'; + if (empty($tooltip)) $tooltip = $task->progress.'% >= '.$langs->trans("TimeConsumed").' '.$progressCalculated.'%'; } } } diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index f5f6bf3dd9d..2aedbd53377 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -85,6 +85,7 @@ ProgressCalculated=Progress on consumption WhichIamLinkedTo=which I'm linked to WhichIamLinkedToProject=which I'm linked to project Time=Time +TimeConsumed=Consumed ListOfTasks=List of tasks GoToListOfTimeConsumed=Go to list of time consumed GanttView=Gantt View From 8dc4e5929c694cf712aa4a0b215081d2b17464a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Jan 2021 12:43:57 +0100 Subject: [PATCH 046/184] Fix var not defined --- htdocs/comm/action/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index b37762a644a..dc0ada64eb3 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -214,6 +214,7 @@ llxHeader('', $langs->trans("Agenda"), $help_url); $form = new Form($db); $companystatic = new Societe($db); $contactstatic = new Contact($db); +$userstatic = new User($db); $now = dol_now(); $nowarray = dol_getdate($now); @@ -1071,7 +1072,6 @@ if (count($listofextcals)) { $event->id = $icalevent['UID']; $event->ref = $event->id; - $userId = $userstatic->findUserIdByEmail($namecal); if (!empty($userId) && $userId > 0) { From 9764f086d30c5cd29292ffe5a8ae3c16a56bedd4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Jan 2021 14:27:42 +0100 Subject: [PATCH 047/184] Fix Field code is mandatory but not field note in tax dictionary --- htdocs/admin/dict.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index d06f8a2ce31..05149030f9e 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -692,7 +692,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'sortorder') continue; // For a column name 'sortorder', we use the field name 'position' if ((!GETPOSTISSET($value) || GETPOST($value) == '') && (!in_array($listfield[$f], array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory - && (!($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 + && ($id != 10 || ($listfield[$f] != 'code' && $listfield[$f] != 'note')) // Field code and note is not mandatory for dictionary table 10 ) ) { $ok = 0; @@ -757,9 +757,9 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($_POST["accountancy_code"] <= 0) $_POST["accountancy_code"] = ''; // If empty, we force to null if ($_POST["accountancy_code_sell"] <= 0) $_POST["accountancy_code_sell"] = ''; // If empty, we force to null if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - if ($id == 10 && GETPOSTISSET("code")) // Spaces are not allowed into code + if ($id == 10 && GETPOSTISSET("code")) // Spaces are not allowed into code for tax dictionary { - $_POST["code"] = preg_replace('/\s/', '', $_POST["code"]); + $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', $_POST["code"]); } // If check ok and action add, add the line @@ -826,8 +826,13 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $result = $db->query($sql); if ($result) // Add is ok { - setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST = array('id'=>$id); // Clean $_POST array, we keep only + setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); + + // Clean $_POST array, we keep only id of dictionary + if ($id == 10 && GETPOST('country', 'int') > 0) { + $search_country_id = GETPOST('country', 'int'); + } + $_POST = array('id'=>$id); } else { if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); From 27c32560c6e359b7fbe6cdd81dbd4201fed05a57 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 5 Jan 2021 14:46:50 +0100 Subject: [PATCH 048/184] Merge develop --- ChangeLog | 6 +- htdocs/commande/list.php | 2 +- htdocs/compta/accounting-files.php | 17 +- htdocs/compta/bank/class/account.class.php | 6 +- .../bank/class/api_bankaccounts.class.php | 26 +- htdocs/compta/paiement.php | 6 +- htdocs/contrat/card.php | 3 +- htdocs/core/boxes/box_fournisseurs.php | 11 +- htdocs/core/class/CMailFile.class.php | 34 +- htdocs/core/class/commonobject.class.php | 1 + htdocs/core/class/html.formmail.class.php | 301 +++++++----------- htdocs/core/lib/functions.lib.php | 2 +- htdocs/core/lib/sendings.lib.php | 2 +- htdocs/core/tpl/object_discounts.tpl.php | 12 +- htdocs/expedition/contact.php | 4 +- htdocs/expedition/list.php | 4 +- htdocs/fourn/commande/list.php | 2 +- htdocs/loan/class/paymentloan.class.php | 2 +- htdocs/loan/payment/payment.php | 4 +- htdocs/reception/contact.php | 9 +- htdocs/reception/list.php | 2 +- htdocs/theme/eldy/info-box.inc.php | 2 +- htdocs/user/list.php | 2 +- .../email_unpaid_invoices_to_customers.php | 2 +- 24 files changed, 208 insertions(+), 254 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4877363e6be..ecf20be261f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -57,7 +57,6 @@ NEW: add option TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT NEW: add option to define a default warehouse at user level NEW: add option to include products without alert in replenish NEW: add order by lastname and firstname by default in get sales representatives -NEW: add param to not show links when output tags NEW: add PDF document templates for warehouses (list of stock) NEW: add a prospect status for the contact with managment of custom icon NEW: add public note on products ; this also partially fix the #14342 @@ -80,7 +79,7 @@ NEW: appearance tab in TakePOS with more visual parameters NEW: better currency rate editor NEW: can build vendor invoice from vendor orders NEW: can change a product in lines of a recurring invoice or contract -NEW: can change size of logo on PDF documents +NEW: can set the size of the logo on PDF documents NEW: can change VAT rate of all lines of a draft object in one step NEW: can define date range of validity of a login during creation NEW: can disable, from edit page, the whole web site @@ -189,7 +188,7 @@ NEW: show line number on intervention card (via MAIN_VIEW_LINE_NUMBER) NEW: Add some fields to link website page to an other object NEW: fill ECM src object fields in dol_add_file_process NEW: conf to allow to show the full tree in warehouse popup -NEW: can use THEME_DARKMODEENABLED=2 for a preview of theme in dark mode +NEW: can use parameter ?THEME_DARKMODEENABLED=2 for a preview of theme in dark mode NEW: can force the antivirus from conf file or autoprepend ini setup NEW: can add event to log into blockedlog module with a constant NEW: add property cssview when declaring fields of an object @@ -208,6 +207,7 @@ NEW: add a message in error_log after detection of SQL or script injection NEW: add validation of MX domain for emails NEW: calculate the virtual stock in transverse mode ( not on getEntity('commande'), ... but on getEntity('stock') ) NEW: Graphics can be horizontal bars +NEW: add param to not show links when output tags APIs NEW: API get contacts list of a given order diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 5fa4a3adfaa..885081e84a1 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -46,7 +46,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; // Load translation files required by the page -$langs->loadLangs(array("orders", 'sendings', 'deliveries', 'companies', 'compta', 'bills', 'stocks')); +$langs->loadLangs(array("orders", 'sendings', 'deliveries', 'companies', 'compta', 'bills', 'stocks', 'products')); $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 734d21b1c87..02098e986ba 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -549,16 +549,17 @@ if (!empty($conf->multicompany->enabled) && is_object($mc)) print '
'; $listofchoices = array( - 'selectinvoices'=>array('label'=>'Invoices', 'lang'=>'bills'), - 'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'lang'=>'bills'), - 'selectexpensereports'=>array('label'=>'ExpenseReports', 'lang'=>'trips'), - 'selectdonations'=>array('label'=>'Donations', 'lang'=>'donation'), - 'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'lang'=>'salaries'), - 'selectsocialcontributions'=>array('label'=>'SocialContributions'), - 'selectvariouspayment'=>array('label'=>'VariousPayment'), - 'selectloanspayment'=>array('label'=>'PaymentLoan'), + 'selectinvoices'=>array('label'=>'Invoices', 'lang'=>'bills', 'enabled' => !empty($conf->facture->enabled)), + 'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'lang'=>'bills', 'enabled' => !empty($conf->supplier_invoice->enabled)), + 'selectexpensereports'=>array('label'=>'ExpenseReports', 'lang'=>'trips', 'enabled' => !empty($conf->expensereport->enabled)), + 'selectdonations'=>array('label'=>'Donations', 'lang'=>'donation', 'enabled' => !empty($conf->don->enabled)), + 'selectsocialcontributions'=>array('label'=>'SocialContributions', 'enabled' => !empty($conf->tax->enabled)), + 'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'lang'=>'salaries', 'enabled' => !empty($conf->salaries->enabled)), + 'selectvariouspayment'=>array('label'=>'VariousPayment', 'enabled' => !empty($conf->banque->enabled)), + 'selectloanspayment'=>array('label'=>'PaymentLoan', 'enabled' => !empty($conf->loan->enabled)), ); foreach ($listofchoices as $choice => $val) { + if (empty($val['enabled'])) continue; // list not qualified $checked = (((!GETPOSTISSET('search') && $action != 'searchfiles') || GETPOST($choice)) ? ' checked="checked"' : ''); print '
'; } diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 76b22e29a96..e0f48e9498b 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -493,9 +493,10 @@ class Account extends CommonObject * @param string $banque Bank of cheque writer * @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on. * @param int $datev Date value + * @param string $num_releve Label of bank receipt for reconciliation * @return int Rowid of added entry, <0 if KO */ - public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null) + public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '') { // Deprecation warning if (is_numeric($oper)) { @@ -555,6 +556,7 @@ class Account extends CommonObject $accline->fk_account = $this->rowid; $accline->fk_type = $oper; $accline->numero_compte = $accountancycode; + $accline->num_releve = $num_releve; if ($num_chq) { $accline->num_chq = $num_chq; @@ -1886,6 +1888,7 @@ class AccountLine extends CommonObject $sql .= ", emetteur,banque"; $sql .= ", rappro"; $sql .= ", numero_compte"; + $sql .= ", num_releve"; $sql .= ") VALUES ("; $sql .= "'".$this->db->idate($this->datec)."'"; $sql .= ", '".$this->db->idate($this->dateo)."'"; @@ -1900,6 +1903,7 @@ class AccountLine extends CommonObject $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null"); $sql .= ", ".(int) $this->rappro; $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''"); + $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null"); $sql .= ")"; dol_syslog(get_class($this)."::insert", LOG_DEBUG); diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 35104e5ed25..9ab02d8b18a 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -466,20 +466,23 @@ class BankAccounts extends DolibarrApi /** * Add a line to an account * - * @param int $id ID of account - * @param int $date Payment date (timestamp) {@from body} {@type timestamp} - * @param string $type Payment mode (TYP,VIR,PRE,LIQ,VAD,CB,CHQ...) {@from body} - * @param string $label Label {@from body} - * @param float $amount Amount (may be 0) {@from body} - * @param int $category Category - * @param string $cheque_number Cheque numberl {@from body} - * @param string $cheque_writer Name of cheque writer {@from body} - * @param string $cheque_bank Bank of cheque writer {@from body} + * @param int $id ID of account + * @param int $date Payment date (timestamp) {@from body} {@type timestamp} + * @param string $type Payment mode (TYP,VIR,PRE,LIQ,VAD,CB,CHQ...) {@from body} + * @param string $label Label {@from body} + * @param float $amount Amount (may be 0) {@from body} + * @param int $category Category + * @param string $cheque_number Cheque numero {@from body} + * @param string $cheque_writer Name of cheque writer {@from body} + * @param string $cheque_bank Bank of cheque writer {@from body} + * @param string $accountancycode Accountancy code {@from body} + * @param int $datev Payment date value (timestamp) {@from body} {@type timestamp} + * @param string $num_releve Bank statement numero {@from body} * @return int ID of line * * @url POST {id}/lines */ - public function addLine($id, $date, $type, $label, $amount, $category = 0, $cheque_number = '', $cheque_writer = '', $cheque_bank = '') + public function addLine($id, $date, $type, $label, $amount, $category = 0, $cheque_number = '', $cheque_writer = '', $cheque_bank = '', $accountancycode = '', $datev = null, $num_releve = '') { if (!DolibarrApiAccess::$user->rights->banque->modifier) { throw new RestException(401); @@ -499,7 +502,8 @@ class BankAccounts extends DolibarrApi $cheque_number, $category, DolibarrApiAccess::$user, - $cheque_writer, $cheque_bank + $cheque_writer, $cheque_bank, $accountancycode, + $datev, $num_releve ); if ($result < 0) { throw new RestException(503, 'Error when adding line to account: '.$account->error); diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index a03fd03ffef..83393a52cb6 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -710,10 +710,10 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie // Price print ''.price($sign * $objp->total_ttc).''; - // Received or paid back + // Received + already paid print ''.price($sign * $paiement); - if ($creditnotes) print '+'.price($creditnotes); - if ($deposits) print '+'.price($deposits); + if ($creditnotes) print '+'.price($creditnotes).''; + if ($deposits) print '+'.price($deposits).''; print ''; // Remain to take or to pay back diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 3906d376243..678ed9bbbd6 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -374,8 +374,7 @@ if (empty($reshook)) $action = 'create'; } } - } elseif ($action == 'classin' && $user->rights->contrat->creer) - { + } elseif ($action == 'classin' && $user->rights->contrat->creer) { $object->setProject(GETPOST('projectid')); } diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index 44e2682585e..7d1c72b3036 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -137,10 +137,13 @@ class box_fournisseurs extends ModeleBoxes $line++; } - if ($num == 0) $this->info_box_contents[$line][0] = array( - 'td' => 'class="center opacitymedium"', - 'text'=>$langs->trans("NoRecordedSuppliers"), - ); + if ($num == 0) { + $langs->load("suppliers"); + $this->info_box_contents[$line][0] = array( + 'td' => 'class="center opacitymedium"', + 'text'=>$langs->trans("NoRecordedSuppliers"), + ); + } $this->db->free($result); } else { diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index c942127aab3..e96adea7531 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -6,7 +6,7 @@ * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2020 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -950,15 +950,14 @@ class CMailFile * Read a file on disk and return encoded content for emails (mode = 'mail') * * @param string $sourcefile Path to file to encode - * @return int <0 if KO, encoded string if OK + * @return int|string <0 if KO, encoded string if OK */ private function _encode_file($sourcefile) { // phpcs:enable $newsourcefile = dol_osencode($sourcefile); - if (is_readable($newsourcefile)) - { + if (is_readable($newsourcefile)) { $contents = file_get_contents($newsourcefile); // Need PHP 4.3 $encoded = chunk_split(base64_encode($contents), 76, $this->eol); // 76 max is defined into http://tools.ietf.org/html/rfc2047 return $encoded; @@ -983,27 +982,24 @@ class CMailFile // phpcs:enable global $conf, $dolibarr_main_data_root; - if (@is_writeable($dolibarr_main_data_root)) // Avoid fatal error on fopen with open_basedir - { + if (@is_writeable($dolibarr_main_data_root)) { // Avoid fatal error on fopen with open_basedir $outputfile = $dolibarr_main_data_root."/dolibarr_mail.log"; $fp = fopen($outputfile, "w"); - if ($this->sendmode == 'mail') - { + if ($this->sendmode == 'mail') { fputs($fp, $this->headers); fputs($fp, $this->eol); // This eol is added by the mail function, so we add it in log fputs($fp, $this->message); - } elseif ($this->sendmode == 'smtps') - { + } elseif ($this->sendmode == 'smtps') { fputs($fp, $this->smtps->log); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on - } elseif ($this->sendmode == 'swiftmailer') - { + } elseif ($this->sendmode == 'swiftmailer') { fputs($fp, $this->logger->dump()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on } fclose($fp); - if (!empty($conf->global->MAIN_UMASK)) + if (!empty($conf->global->MAIN_UMASK)) { @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } } } @@ -1016,8 +1012,7 @@ class CMailFile */ public function checkIfHTML($msg) { - if (!preg_match('/^[\s\t]*styleCSS)) $out .= $this->styleCSS; $out .= "css)) - { + if (!empty($this->css)) { // Style CSS $this->styleCSS = '