diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index cfbeb29c7c3..a2eead267af 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -142,14 +142,14 @@ $enabledisablehtml = $langs->trans("EnablePublicSubscriptionForm").' '; if (empty($conf->global->MEMBER_ENABLE_PUBLIC)) { // Button off, click to enable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Disabled"), 'switch_off'); $enabledisablehtml .= ''; } else { // Button on, click to disable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Activated"), 'switch_on'); $enabledisablehtml .= ''; } @@ -174,8 +174,8 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) $adht = new AdherentType($db); print ''; print $langs->trans("ForceMemberType"); - print ''; - $listofval = array(-1 => $langs->trans("Undefined")); + print ''; + $listofval = array(); $listofval += $adht->liste_array(); $forcetype = $conf->global->MEMBER_NEWFORM_FORCETYPE ?: -1; print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval)>1?1:0); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 1dfb49a6c05..0364b829b2c 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -825,10 +825,13 @@ if ($mode == 'common') $warningmessage = ''; if (!empty($arrayofwarnings[$modName])) { - print ''."\n"; + print ''."\n"; foreach ($arrayofwarnings[$modName] as $keycountry => $cursorwarningmessage) { - $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code); + if (preg_match('/^always/', $keycountry) || ($mysoc->country_code && preg_match('/^'.$mysoc->country_code.'/', $keycountry))) + { + $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code); + } } } if ($objMod->isCoreOrExternalModule() == 'external' && !empty($arrayofwarningsext)) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index d3b4a116123..94b19771159 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -514,9 +514,10 @@ class ActionComm extends CommonObject { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id"); - // Now insert assignedusers + // Now insert assigned users if (!$error) { + //dol_syslog(var_export($this->userassigned, true)); foreach ($this->userassigned as $key => $val) { if (!is_array($val)) // For backward compatibility when val=id @@ -524,16 +525,20 @@ class ActionComm extends CommonObject $val = array('id'=>$val); } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; - $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; + if ($val['id'] > 0) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; + $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; - $resql = $this->db->query($sql); - if (!$resql) - { - $error++; - $this->errors[] = $this->db->lasterror(); - } - //var_dump($sql);exit; + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + dol_syslog('Error to process userassigned: '.$this->db->lasterror(), LOG_ERR); + $this->errors[] = $this->db->lasterror(); + } + //var_dump($sql);exit; + } } } @@ -541,7 +546,7 @@ class ActionComm extends CommonObject { if (!empty($this->socpeopleassigned)) { - foreach ($this->socpeopleassigned as $id => $Tab) + foreach ($this->socpeopleassigned as $id => $val) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)"; @@ -550,6 +555,7 @@ class ActionComm extends CommonObject if (!$resql) { $error++; + dol_syslog('Error to process socpeopleassigned: '.$this->db->lasterror(), LOG_ERR); $this->errors[] = $this->db->lasterror(); } } @@ -558,8 +564,6 @@ class ActionComm extends CommonObject if (!$error) { - $action = 'create'; - // Actions on extra fields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used { diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 2cacb885fa9..3f3bffc6cd2 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -780,6 +780,23 @@ if (empty($reshook)) } } + // If some payments were already done, we change the amount to pay using same prorate + if (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED)) { + $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded. + if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) { + $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc); + foreach($amount_ht as $vatrate => $val) { + $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU'); + $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU'); + $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_ht[$line->tva_tx] = price2num($multicurrency_amount_ht[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_tva[$line->tva_tx] = price2num($multicurrency_amount_tva[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_ttc[$line->tva_tx] = price2num($multicurrency_amount_ttc[$vatrate] * $ratio, 'MU'); + } + } + } + //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit; + // Insert one discount by VAT rate category $discount = new DiscountAbsolute($db); if ($object->type == Facture::TYPE_CREDIT_NOTE) @@ -1520,7 +1537,7 @@ if (empty($reshook)) if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; // View third's localtaxes for NOW and do not use value from origin. - // TODO Is this really what we want ? Yes if source if template invoice but what if proposal or order ? + // TODO Is this really what we want ? Yes if source is template invoice but what if proposal or order ? $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); @@ -5014,7 +5031,9 @@ elseif ($id > 0 || !empty($ref)) print ''.$langs->trans('ConvertExcessReceivedToReduc').''; } // For credit note - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate && $object->getSommePaiement() == 0) { + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate + && (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) + ) { print ''.$langs->trans('ConvertToReduc').''; } // For deposit invoice diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 9def117ef21..ee0794e4b16 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -107,7 +107,8 @@ abstract class CommonInvoice extends CommonObject } /** - * Return amount of payments already done + * Return amount of payments already done. This must include ONLY the record into the payment table. + * Payments dones using discounts, credit notes, etc are not included. * * @param int $multicurrency Return multicurrency_amount instead of amount * @return int Amount of payment already done, <0 if KO diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index 304a7a248a3..460dbe6e90c 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -109,8 +109,10 @@ class Interfaces $handle = opendir($newdir); if (is_resource($handle)) { + $fullpathfiles = array(); while (($file = readdir($handle)) !== false) { + $reg=array(); if (is_readable($newdir."/".$file) && preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php$/i', $file, $reg)) { $part1 = $reg[1]; @@ -274,6 +276,7 @@ class Interfaces { while (($file = readdir($handle)) !== false) { + $reg = array(); if (is_readable($newdir.'/'.$file) && preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/', $file, $reg)) { if (preg_match('/\.back$/', $file)) continue; diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index e54de5a91d2..4f6d6750040 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -221,7 +221,7 @@ class Translate if (empty($langofdir)) // This may occurs when load is called without setting the language and without providing a value for forcelangdir { - dol_syslog("Error: ".get_class($this)."::Load was called but language was not set yet with langs->setDefaultLang(). Nothing will be loaded.", LOG_WARNING); + dol_syslog("Error: ".get_class($this)."::load was called for domain=".$domain." but language was not set yet with langs->setDefaultLang(). Nothing will be loaded.", LOG_WARNING); return -1; } @@ -428,7 +428,7 @@ class Translate if (empty($langofdir)) // This may occurs when load is called without setting the language and without providing a value for forcelangdir { - dol_syslog("Error: ".get_class($this)."::Load was called but language was not set yet with langs->setDefaultLang(). Nothing will be loaded.", LOG_WARNING); + dol_syslog("Error: ".get_class($this)."::loadFromDatabase was called but language was not set yet with langs->setDefaultLang(). Nothing will be loaded.", LOG_WARNING); return -1; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7d82336dd16..909d16d39e6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4677,6 +4677,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer = "", $thirdparty_sell dol_syslog("get_localtax tva=".$vatrate." local=".$local." thirdparty_buyer id=".(is_object($thirdparty_buyer) ? $thirdparty_buyer->id : '')."/country_code=".(is_object($thirdparty_buyer) ? $thirdparty_buyer->country_code : '')." thirdparty_seller id=".$thirdparty_seller->id."/country_code=".$thirdparty_seller->country_code." thirdparty_seller localtax1_assuj=".$thirdparty_seller->localtax1_assuj." thirdparty_seller localtax2_assuj=".$thirdparty_seller->localtax2_assuj); $vatratecleaned = $vatrate; + $reg = array(); if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "xx (yy)" { $vatratecleaned = trim($reg[1]); @@ -4921,13 +4922,14 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local); // Search local taxes - $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy"; + $sql = "SELECT t.taux as rate, t.code, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t"; if ($firstparamisid) $sql .= " WHERE t.rowid = ".(int) $vatrate; else { $vatratecleaned = $vatrate; $vatratecode = ''; + $reg = array(); if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "x.x (yy)" { $vatratecleaned = $reg[1]; @@ -4945,17 +4947,20 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi if ($resql) { $obj = $db->fetch_object($resql); + + $vateratestring = $obj->rate.($obj->code ? ' ('.$obj->code.')' : ''); + if ($local == 1) { - return array($obj->localtax1_type, get_localtax($vatrate, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); + return array($obj->localtax1_type, get_localtax($vateratestring, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); } elseif ($local == 2) { - return array($obj->localtax2_type, get_localtax($vatrate, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); + return array($obj->localtax2_type, get_localtax($vateratestring, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); } else { - return array($obj->localtax1_type, get_localtax($vatrate, 1, $buyer, $seller), $obj->localtax2_type, get_localtax($vatrate, 2, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); + return array($obj->localtax1_type, get_localtax($vateratestring, 1, $buyer, $seller), $obj->localtax2_type, get_localtax($vateratestring, 2, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); } } diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php index 83752de24e7..83495ca1af6 100644 --- a/htdocs/core/modules/modCashDesk.class.php +++ b/htdocs/core/modules/modCashDesk.class.php @@ -99,7 +99,7 @@ class modCashDesk extends DolibarrModules 'type'=>'top', // This is a Top menu entry 'titre'=>'PointOfSaleShort', 'mainmenu'=>'cashdesk', - 'url'=>'/cashdesk/index.php?user=__LOGIN__', + 'url'=>'/cashdesk/index.php?user=__USER_LOGIN__', 'langs'=>'cashdesk', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>900, 'enabled'=>'$conf->cashdesk->enabled', diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 61536e1d154..3e42e18e3f3 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -436,7 +436,7 @@ if (is_object($objectline)) { } if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required { - ?> +?> > global->MAIN_VIEW_LINE_NUMBER)) { print ''; } ?> @@ -476,80 +476,82 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat } } print ''; - print ''; - print "\n"; + ?> + + +\n"; -if (!empty($usemargins) && $user->rights->margins->creer) -{ - ?> - - /* Some js test when we click on button "Add" */ - jQuery(document).ready(function() { - global->DISPLAY_MARGIN_RATES)) { ?> - $("input[name='np_marginRate']:first").blur(function(e) { - return checkFreeLine(e, "np_marginRate"); - }); - global->DISPLAY_MARK_RATES)) { ?> - $("input[name='np_markRate']:first").blur(function(e) { - return checkFreeLine(e, "np_markRate"); - }); - - }); - - /* TODO This does not work for number with thousand separator that is , */ - function checkFreeLine(e, npRate) - { - var buying_price = $("input[name='buying_price']:first"); - var remise = $("input[name='remise_percent']:first"); - - var rate = $("input[name='"+npRate+"']:first"); - if (rate.val() == '') - return true; - - if (! $.isNumeric(rate.val().replace(',','.'))) - { - 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; - } - - var price = 0; - remisejs=price2numjs(remise.val()); - - if (remisejs != 100) // If a discount not 100 or no discount - { - if (remisejs == '') remisejs=0; - - bpjs=price2numjs(buying_price.val()); - ratejs=price2numjs(rate.val()); - - if (npRate == "np_marginRate") - price = ((bpjs * (1 + ratejs / 100)) / (1 - remisejs / 100)); - else if (npRate == "np_markRate") - price = ((bpjs / (1 - ratejs / 100)) / (1 - remisejs / 100)); - } - $("input[name='price_ht']:first").val(price); // TODO Must use a function like php price to have here a formated value - - return true; - } + if (!empty($usemargins) && $user->rights->margins->creer) + { + ?> + /* Some js test when we click on button "Add" */ + jQuery(document).ready(function() { + if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { ?> + $("input[name='np_marginRate']:first").blur(function(e) { + return checkFreeLine(e, "np_marginRate"); + }); + global->DISPLAY_MARK_RATES)) { ?> + $("input[name='np_markRate']:first").blur(function(e) { + return checkFreeLine(e, "np_markRate"); + }); + + }); + + /* TODO This does not work for number with thousand separator that is , */ + function checkFreeLine(e, npRate) + { + var buying_price = $("input[name='buying_price']:first"); + var remise = $("input[name='remise_percent']:first"); + + var rate = $("input[name='"+npRate+"']:first"); + if (rate.val() == '') + return true; + + if (! $.isNumeric(rate.val().replace(',','.'))) + { + 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; + } + + var price = 0; + remisejs=price2numjs(remise.val()); + + if (remisejs != 100) // If a discount not 100 or no discount + { + if (remisejs == '') remisejs=0; + + bpjs=price2numjs(buying_price.val()); + ratejs=price2numjs(rate.val()); + + if (npRate == "np_marginRate") + price = ((bpjs * (1 + ratejs / 100)) / (1 - remisejs / 100)); + else if (npRate == "np_markRate") + price = ((bpjs / (1 - ratejs / 100)) / (1 - remisejs / 100)); + } + $("input[name='price_ht']:first").val(price); // TODO Must use a function like php price to have here a formated value + + return true; + } + + /* JQuery for product free or predefined select */ jQuery(document).ready(function() { @@ -621,199 +623,200 @@ if (!empty($usemargins) && $user->rights->margins->creer) /* When changing predefined product, we reload list of supplier prices required for margin combo */ $("#idprod, #idprodfournprice").change(function() { - console.log("#idprod, #idprodfournprice change triggered"); + console.log("#idprod, #idprodfournprice change triggered this.val = "+$(this).val()); - setforpredef(); // TODO Keep vat combo visible and set it to first entry into list that match result of get_default_tva + setforpredef(); // TODO Keep vat combo visible and set it to first entry into list that match result of get_default_tva - jQuery('#trlinefordates').show(); - global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT)) - { - ?> - // get the HT price for the product and display it - $.post('/product/ajax/products.php?action=fetch', { 'id': $(this).val(), 'socid' : socid; ?> }, function(data) { - jQuery("#price_ht").val(data.price_ht); - }, - 'json'); + jQuery('#trlinefordates').show(); rights->margins->creer) - { - $langs->load('stocks'); + if (empty($conf->global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT) && empty($senderissupplier)) + { + ?> + // Get the HT price for the product and display it + $.post('/product/ajax/products.php?action=fetch', + { 'id': $(this).val(), 'socid' : socid; ?> }, + function(data) { jQuery("#price_ht").val(data.price_ht); }, + 'json' + ); + rights->margins->creer) + { + $langs->load('stocks'); + ?> + + /* Code for margin */ + $("#fournprice_predef").find("option").remove(); + $("#fournprice_predef").hide(); + $("#buying_price").val("").show(); + /* Call post to load content of combo list fournprice_predef */ + $.post('/fourn/ajax/getSupplierPrices.php?bestpricefirst=1', { 'idprod': $(this).val() }, function(data) { + if (data && data.length > 0) + { + var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; + + var bestpriceid = 0; var bestpricevalue = 0; + var pmppriceid = 0; var pmppricevalue = 0; + var costpriceid = 0; var costpricevalue = 0; + + /* setup of margin calculation */ + var defaultbuyprice = 'global->MARGIN_TYPE)) + { + if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; + if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; + if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; + } ?>'; + console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); + + var i = 0; + $(data).each(function() { + if (this.id != 'pmpprice' && this.id != 'costprice') + { + i++; + this.price = parseFloat(this.price); // to fix when this.price >0 + // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) + //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); + if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0 + } + if (this.id == 'pmpprice') + { + // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) + //console.log("id="+this.id+"-price="+this.price); + if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) + { + if (this.price > 0) { + defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; + //console.log("pmppricevalue="+pmppricevalue); + } + } + } + if (this.id == 'costprice') + { + // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) + //console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); + if ('costprice' == defaultbuyprice) + { + if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } + else if (pmppricevalue > 0) { defaultkey = pmppriceid; defaultprice = pmppricevalue; } + } + } + options += ''; + }); + options += ''; + + console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice); + + $("#fournprice_predef").html(options).show(); + if (defaultkey != '') + { + $("#fournprice_predef").val(defaultkey); + } + + /* At loading, no product are yet selected, so we hide field of buying_price */ + $("#buying_price").hide(); + + /* Define default price at loading */ + var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); + $("#buying_price").val(defaultprice); + + $("#fournprice_predef").change(function() { + console.log("change on fournprice_predef"); + /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ + var linevalue=$(this).find('option:selected').val(); + var pricevalue = $(this).find('option:selected').attr("price"); + if (linevalue != 'inputprice' && linevalue != 'pmpprice') { + $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ + } + if (linevalue == 'inputprice') { + $('#buying_price').show(); + } + if (linevalue == 'pmpprice') { + $("#buying_price").val(pricevalue); + $('#buying_price').hide(); + } + }); + } + }, + 'json'); + + - /* Code for margin */ - $("#fournprice_predef").find("option").remove(); - $("#fournprice_predef").hide(); - $("#buying_price").val("").show(); - /* Call post to load content of combo list fournprice_predef */ - $.post('/fourn/ajax/getSupplierPrices.php?bestpricefirst=1', { 'idprod': $(this).val() }, function(data) { - if (data && data.length > 0) + /* To process customer price per quantity */ + var pbq = parseInt($('option:selected', this).attr('data-pbq')); + var pbqqty = parseFloat($('option:selected', this).attr('data-pbqqty')); + var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent')); + + if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && typeof pbq !== "undefined") { - var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; - - var bestpriceid = 0; var bestpricevalue = 0; - var pmppriceid = 0; var pmppricevalue = 0; - var costpriceid = 0; var costpricevalue = 0; - - /* setup of margin calculation */ - var defaultbuyprice = 'global->MARGIN_TYPE)) + console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent); + jQuery("#pbq").val(pbq); + if (jQuery("#qty").val() < pbqqty) + { + jQuery("#qty").val(pbqqty); + } + if (jQuery("#remise_percent").val() < pbqpercent) + { + jQuery("#remise_percent").val(pbqpercent); + } + } + else { - if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; - if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; - if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; - } ?>'; - console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); + jQuery("#pbq").val(''); + } - var i = 0; - $(data).each(function() { - if (this.id != 'pmpprice' && this.id != 'costprice') + /* To set focus */ + if (jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val() > 0) { - i++; - this.price = parseFloat(this.price); // to fix when this.price >0 - // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) - //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); - if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 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(); } + } } - if (this.id == 'pmpprice') - { - // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) - //console.log("id="+this.id+"-price="+this.price); - if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) - { - if (this.price > 0) { - defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; - //console.log("pmppricevalue="+pmppricevalue); - } - } - } - if (this.id == 'costprice') - { - // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) - //console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); - if ('costprice' == defaultbuyprice) - { - if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } - else if (pmppricevalue > 0) { defaultkey = pmppriceid; defaultprice = pmppricevalue; } - } - } - options += ''; - }); - options += ''; - - console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice); - - $("#fournprice_predef").html(options).show(); - if (defaultkey != '') - { - $("#fournprice_predef").val(defaultkey); - } - - /* At loading, no product are yet selected, so we hide field of buying_price */ - $("#buying_price").hide(); - - /* Define default price at loading */ - var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); - $("#buying_price").val(defaultprice); - - $("#fournprice_predef").change(function() { - console.log("change on fournprice_predef"); - /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ - var linevalue=$(this).find('option:selected').val(); - var pricevalue = $(this).find('option:selected').attr("price"); - if (linevalue != 'inputprice' && linevalue != 'pmpprice') { - $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ - } - if (linevalue == 'inputprice') { - $('#buying_price').show(); - } - if (linevalue == 'pmpprice') { - $("#buying_price").val(pricevalue); - $('#buying_price').hide(); - } - }); - } - }, - 'json'); - - - - /* To process customer price per quantity */ - var pbq = parseInt($('option:selected', this).attr('data-pbq')); - var pbqqty = parseFloat($('option:selected', this).attr('data-pbqqty')); - var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent')); - - if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && typeof pbq !== "undefined") - { - console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent); - jQuery("#pbq").val(pbq); - if (jQuery("#qty").val() < pbqqty) - { - jQuery("#qty").val(pbqqty); - } - if (jQuery("#remise_percent").val() < pbqpercent) - { - jQuery("#remise_percent").val(pbqpercent); - } - } - else - { - jQuery("#pbq").val(''); - } - - /* To set focus */ - if (jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').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(); } - } - } }); - + setforpredef(); - + }); /* Function to set fields from choice */ function setforfree() { - console.log("Call setforfree. We show most fields"); - jQuery("#idprodfournprice").val('0'); // Set cursor on not selected product - jQuery("#prod_entry_mode_free").prop('checked',true).change(); - jQuery("#prod_entry_mode_predef").prop('checked',false).change(); - jQuery("#search_idprod, #idprod, #search_idprodfournprice, #buying_price").val(''); - jQuery("#price_ht, #multicurrency_price_ht, #price_ttc, #price_ttc, #fourn_ref, #tva_tx, #buying_price, #title_vat, #title_up_ht, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").show(); - jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").show(); - jQuery("#fournprice_predef").hide(); + console.log("Call setforfree. We show most fields"); + jQuery("#idprodfournprice").val('0'); // Set cursor on not selected product + jQuery("#prod_entry_mode_free").prop('checked',true).change(); + jQuery("#prod_entry_mode_predef").prop('checked',false).change(); + jQuery("#search_idprod, #idprod, #search_idprodfournprice, #buying_price").val(''); + jQuery("#price_ht, #multicurrency_price_ht, #price_ttc, #price_ttc, #fourn_ref, #tva_tx, #buying_price, #title_vat, #title_up_ht, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").show(); + jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").show(); + jQuery("#fournprice_predef").hide(); } function setforpredef() { - console.log("Call setforpredef. We hide some fields and show dates"); - jQuery("#select_type").val(-1); - jQuery("#prod_entry_mode_free").prop('checked',false).change(); - jQuery("#prod_entry_mode_predef").prop('checked',true).change(); - global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT)) { ?> - jQuery("#price_ht").val('').show(); - jQuery("#multicurrency_price_ht").val('').show(); - - jQuery("#price_ht").val('').hide(); - jQuery("#multicurrency_price_ht").val('').hide(); - - jQuery("#price_ht").val(''); - jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_vat, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").hide(); - jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").hide(); - jQuery("#buying_price").show(); - jQuery('#trlinefordates, .divlinefordates').show(); + console.log("Call setforpredef. We hide some fields and show dates"); + jQuery("#select_type").val(-1); + jQuery("#prod_entry_mode_free").prop('checked',false).change(); + jQuery("#prod_entry_mode_predef").prop('checked',true).change(); + global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT)) { ?> + jQuery("#price_ht").val('').show(); + jQuery("#multicurrency_price_ht").val('').show(); + + jQuery("#price_ht").val('').hide(); + jQuery("#multicurrency_price_ht").val('').hide(); + + jQuery("#price_ht").val(''); + jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_vat, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").hide(); + jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").hide(); + jQuery("#buying_price").show(); + jQuery('#trlinefordates, .divlinefordates').show(); } - - - + +\n"; diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index e72da40d6b0..26958aed875 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -954,8 +954,7 @@ class InterfaceActionsAuto extends DolibarrTriggers } else { - $error ="Failed to insert event : ".$actioncomm->error." ".join(',', $actioncomm->errors); - $this->error=$error; + $this->error="Failed to insert event : ".$actioncomm->error." ".join(',', $actioncomm->errors); $this->errors=$actioncomm->errors; dol_syslog("interface_modAgenda_ActionsAuto.class.php: ".$this->error, LOG_ERR); diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php index 16d5a3659a5..5744a29db48 100644 --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php @@ -118,9 +118,6 @@ class InterfaceStripe // Data and type of action are stored into $object and $action global $langs, $db, $conf; - // Load translation files required by the page - $langs->loadLangs(array("members","other","users","mails")); - require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $stripe = new Stripe($db); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index dba7392a9e4..807804ed5fe 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1639,7 +1639,7 @@ class FactureFournisseur extends CommonInvoice $result = $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$ref_supplier/$this->fk_soc if ($result > 0) { - $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice + if (empty($pu)) $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice // is remise percent not keyed but present for the product we add it if ($remise_percent == 0 && $prod->remise_percent != 0) @@ -1691,6 +1691,7 @@ class FactureFournisseur extends CommonInvoice $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty); // Clean vat code + $reg = array(); $vat_src_code = ''; if (preg_match('/\((.*)\)/', $txtva, $reg)) { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 957561466c7..4e6523ff6cb 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -361,7 +361,7 @@ if (empty($reshook)) else { $idprod = GETPOST('idprod', 'int'); - $price_ht = ''; + $price_ht = GETPOST('price_ht'); $tva_tx = ''; } @@ -420,15 +420,14 @@ if (empty($reshook)) } } - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - if (($prod_entry_mode != 'free') && empty($error)) // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or '' + if ($prod_entry_mode != 'free' && empty($error)) // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or '' { $productsupplier = new ProductFournisseur($db); $idprod = 0; if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') $idprod = -99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...) + + $reg = array(); if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) { $idprod = $reg[1]; @@ -470,7 +469,22 @@ if (empty($reshook)) if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; - $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); + if ($price_ht != '' || $price_ht_devise != '') { + $price_base_type = 'HT'; + $pu = price2num($price_ht, 'MU'); + $pu_ht_devise = price2num($price_ht_devise, 'MU'); + } else { + $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); + if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency + $pu = $productsupplier->fourn_pu; + $pu_ht_devise = 0; + } else { + $pu = $productsupplier->fourn_pu; + $pu_ht_devise = $productsupplier->fourn_multicurrency_unitprice; + /*var_dump($pu); + var_dump($pu_ht_devise);exit;*/ + } + } $ref_supplier = $productsupplier->ref_supplier; @@ -480,7 +494,6 @@ if (empty($reshook)) $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr); - $pu = $productsupplier->fourn_pu; if (empty($pu)) $pu = 0; // If pu is '' or null, we force to have a numeric value $result = $object->addline( @@ -503,7 +516,9 @@ if (empty($reshook)) $date_end, $array_options, $productsupplier->fk_unit, - $productsupplier->fourn_multicurrency_unitprice + $pu_ht_devise, + '', + 0 ); } if ($idprod == -99 || $idprod == 0) @@ -2200,7 +2215,7 @@ elseif (!empty($object->id)) print ''; - if (!empty($conf->multicurrency->enabled)) + if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) { // Multicurrency Amount HT print ''; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 9f08e944ee0..1e0ea5ba92a 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -99,8 +99,11 @@ if (!empty($user->socid)) $socid = $user->socid; $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', 'rowid', $isdraft); +$usercancreate = $user->rights->fournisseur->facture->creer; + $permissionnote = $user->rights->fournisseur->facture->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->fournisseur->facture->creer; // Used by the include of actions_dellink.inc.php +$permissiontoedit = $user->rights->fournisseur->facture->creer; // Used by the include of actions_lineupdown.inc.php $permissiontoadd = $user->rights->fournisseur->facture->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php @@ -402,7 +405,7 @@ if (empty($reshook)) $result = $object->update($user); if ($result < 0) dol_print_error($db, $object->error); } - elseif ($action == "setabsolutediscount" && $user->rights->fournisseur->facture->creer) + elseif ($action == "setabsolutediscount" && $usercancreate) { // POST[remise_id] or POST[remise_id_for_payment] @@ -460,7 +463,7 @@ if (empty($reshook)) } } // Convertir en reduc - elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer) + elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $usercancreate) { $object->fetch($id); $object->fetch_thirdparty(); @@ -472,13 +475,14 @@ if (empty($reshook)) $canconvert = 0; if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc) - if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not refunded completely and not already converted and amount of payment is 0 (see also the real condition used as the condition to show button converttoreduc) if ($canconvert) { $db->begin(); $amount_ht = $amount_tva = $amount_ttc = array(); - + $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array(); + // Loop on each vat rate $i = 0; foreach ($object->lines as $line) @@ -492,6 +496,20 @@ if (empty($reshook)) } } + // If some payments were already done, we change the amount to pay using same prorate + if (! empty($conf->global->SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED)) { + $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded. + if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) { + $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc); + foreach($amount_ht as $vatrate => $val) { + $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU'); + $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU'); + $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU'); + } + } + } + //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit; + // Insert one discount by VAT rate category $discount = new DiscountAbsolute($db); if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) @@ -513,6 +531,7 @@ if (empty($reshook)) { // If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT + // Total payments $sql = 'SELECT SUM(pf.amount) as total_paiements'; $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')'; @@ -526,7 +545,20 @@ if (empty($reshook)) $res = $db->fetch_object($resql); $total_paiements = $res->total_paiements; - $discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc; + // Total credit note and deposit + $total_creditnote_and_deposit = 0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql .= " re.description, re.fk_invoice_supplier_source"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re"; + $sql .= " WHERE fk_invoice_supplier = ".$object->id; + $resql = $db->query($sql); + if (!empty($resql)) { + while ($obj = $db->fetch_object($resql)) { + $total_creditnote_and_deposit += $obj->amount_ttc; + } + } else dol_print_error($db); + + $discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $object->total_ttc; $discount->amount_tva = 0; $discount->tva_tx = 0; @@ -600,7 +632,7 @@ if (empty($reshook)) } // Create - elseif ($action == 'add' && $user->rights->fournisseur->facture->creer) + elseif ($action == 'add' && $usercancreate) { if ($socid > 0) $object->socid = GETPOST('socid', 'int'); @@ -632,7 +664,7 @@ if (empty($reshook)) if (!$error) { // This is a replacement invoice - $result = $object->fetch(GETPOST('fac_replacement'), 'int'); + $result = $object->fetch(GETPOST('fac_replacement', 'int')); $object->fetch_thirdparty(); $object->ref = GETPOST('ref', 'nohtml'); @@ -1143,7 +1175,7 @@ if (empty($reshook)) else { $idprod = GETPOST('idprod', 'int'); - $price_ht = ''; + $price_ht = GETPOST('price_ht'); $tva_tx = ''; } @@ -1209,6 +1241,7 @@ if (empty($reshook)) $idprod = 0; if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') $idprod = -99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...) + $reg = array(); if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) { $idprod = $reg[1]; @@ -1250,7 +1283,20 @@ if (empty($reshook)) if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); $type = $productsupplier->type; - $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); + if ($price_ht != '' || $price_ht_devise != '') { + $price_base_type = 'HT'; + $pu = price2num($price_ht, 'MU'); + $pu_ht_devise = price2num($price_ht_devise, 'MU'); + } else { + $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); + if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency + $pu = $productsupplier->fourn_pu; + $pu_ht_devise = 0; + } else { + $pu = $productsupplier->fourn_pu; + $pu_ht_devise = $productsupplier->fourn_multicurrency_unitprice; + } + } $ref_supplier = $productsupplier->ref_supplier; @@ -1260,7 +1306,6 @@ if (empty($reshook)) $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr); - $pu = $productsupplier->fourn_pu; if (empty($pu)) $pu = 0; // If pu is '' or null, we force to have a numeric value $result = $object->addline( @@ -1283,8 +1328,9 @@ if (empty($reshook)) $array_options, $productsupplier->fk_unit, 0, - $productsupplier->fourn_multicurrency_unitprice, - $ref_supplier + $pu_ht_devise, + $ref_supplier, + '' ); } if ($idprod == -99 || $idprod == 0) @@ -3129,7 +3175,9 @@ else print '
'.$langs->trans('ConvertExcessPaidToReduc').'
'; } // For credit note - if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer && $object->getSommePaiement() == 0) { + if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer + && (! empty($conf->global->SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) + ) { print '
'.$langs->trans('ConvertToReduc').'
'; } // For deposit invoice diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index 2ef48bc9f0b..4d29f03003e 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -180,7 +180,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ /*************************************************************************************** * - * Migration des donnees + * Migration of data * ***************************************************************************************/ $db->begin(); @@ -553,6 +553,11 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ print '
'.$form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0).'
'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX."const SET VALUE = 'torefresh' WHERE name = 'MAIN_FIRST_PING_OK_ID'"; + $db->query($sql, 1); + + // We always commit. // Process is designed so we can run it several times whatever is situation. $db->commit(); diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index f117dce2509..b5edc0c919d 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2552,7 +2552,7 @@ if (!function_exists("llxFooter")) print ''."\n"; // Add code for the asynchronous anonymous first ping (for telemetry) - // You can use &forceping=1 in parameters to force the ping. + // You can use &forceping=1 in parameters to force the ping if the ping was already sent. if (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || GETPOST('forceping', 'alpha')) { //print ''; @@ -2562,14 +2562,14 @@ if (!function_exists("llxFooter")) || GETPOST('forceping', 'alpha')) { if (strpos('alpha', DOL_VERSION) > 0) { - print "\n\n"; + print "\n\n"; } - elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id])) + elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id])) // Cookie is set when we uncheck the checkbox in the installation wizard. { include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; print "\n".''."\n"; - print "\n\n"; + print "\n\n"; $url_for_ping = (empty($conf->global->MAIN_URL_FOR_PING) ? "https://ping.dolibarr.org/" : $conf->global->MAIN_URL_FOR_PING); ?>