diff --git a/ChangeLog b/ChangeLog index 1fe09d88ccf..d5a0533b2de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,24 +40,26 @@ For users: - New: Add Maghreb regions and departments. - New: A more responsive desgin for statistic box of home page. - Qual: Implement same rule for return value of all command line scripts (0 when success, <>0 if error). -- New: [ task #1005 ] Adapting to Spanish legislation bill numbering. -- New: [ task #1011 ] Now supplier order and invoice deal with payment terms and mode. -- New: [ task #1014 ] Add option to recursivly add parent category. -- New: [ task #1016 ] Can define a specific numbering for deposits. -- New: [ task #918 ] Stock replenishment. -- Fix: [ bug #992 ] Proforma invoices don't have a separated numeric count. -- New: Add pdf link into supplier invoice list and supplier order list. -- New: Genrate auto the PDF for supplier invoice. -- New: Add category into filter webservice thirdparty method getListOfThirdParties. -- New: Allow to define margin or mark rate during quoting, ordering, invoicing. -- New: User permissions on margin module. -- New: Add ref supplier into muscadet model. +- New: [ task #1005 ] Adapting to Spanish legislation bill numbering +- New: [ task #1011 ] Now supplier order and invoice deal with payment terms and mode +- New: [ task #1014 ] Add option to recursivly add parent category +- New: [ task #1016 ] Can define a specific numbering for deposits +- New: [ task #918 ] Stock replenishment +- Fix: [ bug #992 ] Proforma invoices don't have a separated numeric count +- New : Add pdf link into supplier invoice list and supplier order list +- New : Genrate auto the PDF for supplier invoice +- New : Add category into filter webservice thirdparty method getListOfThirdParties +- New : Allow to define margin or mark rate during quoting, ordering, invoicing +- New : User permissions on margin module +- New : Add ref supplier into muscadet model +- New : Add ability to copy contact address to clipboard - New: Can use tag {mm} before {yy} even when there is a reset into numbering masks. - New: [ task #1060 ] Register fields localtax(1|2)_type into details tables. - New: [ task #923 ] Localtax support for ODT templates. - New: [ task #90 ] Barcode search. - New: Can send an email from thirdparty card. - New: Can cancel holidays that were previously validated. +- Fix: [bug #1022] correct margin calculation for credit notes. For translators: - Qual: Normalized sort order of all languages files with english reference files. diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 6d89e18c77d..aef2289ab2e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3129,53 +3129,80 @@ abstract class CommonObject // calcul des marges if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) { // remise + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit - $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_products'] += $pa; + $marginInfos['pv_products'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_products'] += $pv - $pa; } elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service - $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_services'] += $pa; + $marginInfos['pv_services'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_services'] += $pv - $pa; } elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100)); + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; } } else { $type=$line->product_type?$line->product_type:$line->fk_product_type; if ($type == 0) { // product - $marginInfos['pa_products'] += $line->qty * $line->pa_ht; - $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_products'] += $pa; + $marginInfos['pv_products'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_products'] += $pv - $pa; } elseif ($type == 1) { // service - $marginInfos['pa_services'] += $line->qty * $line->pa_ht; - $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_services'] += $pa; + $marginInfos['pv_services'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_services'] += $pv - $pa; } } } - - $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products']; if ($marginInfos['pa_products'] > 0) $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5); if ($marginInfos['pv_products'] > 0) $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5); - $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services']; if ($marginInfos['pa_services'] > 0) $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5); if ($marginInfos['pv_services'] > 0) $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5); - $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($marginInfos['pv_total'] < 0) + $marginInfos['total_margin'] = -1 * (abs($marginInfos['pv_total']) - $marginInfos['pa_total']); + else + $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; if ($marginInfos['pa_total'] > 0) $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5); if ($marginInfos['pv_total'] > 0) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index f9c731c097a..5d57abe119c 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -5,7 +5,8 @@ * Copyright (C) 2010-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Juanjo Menent - * + * Copyright (C) 2013 Christophe Battarel + * * * 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 * the Free Software Foundation; either version 3 of the License, or @@ -546,7 +547,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print "\n".''."\n"; - $colspan=6; + $colspan=8; print ''; print ''; print ''; @@ -561,10 +562,16 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $colspan++; print ''; } + if ($user->rights->societe->contact->creer) + { + $colspan++; + print ''; + } print ""; $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.statut "; + $sql .= ", p.civilite, p.address, p.zip, p.town"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; $sql .= " WHERE p.fk_soc = ".$object->id; $sql .= " ORDER by p.datec"; @@ -592,17 +599,17 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print ''; - $country_code = getCountry($obj->fk_pays, 2); + $country_code = getCountry($obj->fk_pays, 'all'); // Lien click to dial print ''; print ''; print ''; print ''; elseif ($obj->statut==1) print ''; + + // copy in clipboard + $coords = ''; + if (!empty($object->name)) + $coords .= addslashes($object->name)."
"; + if (!empty($obj->civilite)) + $coords .= addslashes($obj->civilite).' '; + if (!empty($obj->firstname)) + $coords .= addslashes($obj->firstname).' '; + if (!empty($obj->lastname)) + $coords .= addslashes($obj->lastname); + $coords .= "
"; + if (!empty($obj->address)) + { + $coords .= addslashes(dol_nl2br($obj->address,1,true))."
"; + if (!empty($obj->cp)) + $coords .= addslashes($obj->zip).' '; + if (!empty($obj->ville)) + $coords .= addslashes($obj->town); + if (!empty($obj->pays)) + $coords .= "
".addslashes($country_code['label']); + } + elseif (!empty($object->address)) + { + $coords .= addslashes(dol_nl2br($object->address,1,true))."
"; + if (!empty($object->zip)) + $coords .= addslashes($object->zip).' '; + if (!empty($object->town)) + $coords .= addslashes($object->town); + if (!empty($object->country)) + $coords .= "
".addslashes($object->country); + } + print ''; + if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) { print '
'.$langs->trans("Name").''.$langs->trans("Poste").'  
'.$obj->poste.''; - print dol_print_phone($obj->phone,$country_code,$obj->rowid,$object->id,'AC_TEL'); + print dol_print_phone($obj->phone,$country_code['code'],$obj->rowid,$object->id,'AC_TEL'); print ''; - print dol_print_phone($obj->phone_mobile,$country_code,$obj->rowid,$object->id,'AC_TEL'); + print dol_print_phone($obj->phone_mobile,$country_code['code'],$obj->rowid,$object->id,'AC_TEL'); print ''; - print dol_print_phone($obj->fax,$country_code,$obj->rowid,$object->id,'AC_FAX'); + print dol_print_phone($obj->fax,$country_code['code'],$obj->rowid,$object->id,'AC_FAX'); print ''; print dol_print_email($obj->email,$obj->rowid,$object->id,'AC_EMAIL'); @@ -610,6 +617,42 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') if ($obj->statut==0) print ''.$langs->trans('Disabled').' '.img_picto($langs->trans('StatusContactDraftShort'),'statut0').''.$langs->trans('Enabled').' '.img_picto($langs->trans('StatusContactValidatedShort'),'statut1').''; + print img_picto($langs->trans("Address"), 'object_address.png'); + print ''; @@ -648,6 +691,20 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print "\n
\n"; print "
\n"; +?> + + + function copyToClipboard (text) { + text = text.replace(/
/g,"\n"); + var newElem = "

'.$langs->trans('HelpCopyToClipboard').'"; + $("#dialog").html(newElem); + $( "#dialog" ).dialog(); + $("#coords").select(); + return false; + } + '; return $i; } diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index ac05f71b901..c77e24e8bbd 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -141,13 +141,21 @@ if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { if (! empty($conf->global->DISPLAY_MARGIN_RATES)) { $margin_rate = (isset($_POST["marginRate"])?$_POST["marginRate"]:(($line->pa_ht == 0)?'':price($line->marge_tx))); - echo '%'; + // if credit note, dont allow to modify margin + if ($line->subprice < 0) + echo ''.$margin_rate.'%'; + else + echo '%'; $coldisplay++; } elseif (! empty($conf->global->DISPLAY_MARK_RATES)) { $mark_rate = (isset($_POST["markRate"])?$_POST["markRate"]:price($line->marque_tx)); - echo '%'; + // if credit note, dont allow to modify margin + if ($line->subprice < 0) + echo ''.$mark_rate.'%'; + else + echo '%'; $coldisplay++; } } diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 35788d208fa..d3396ea788a 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -658,6 +658,7 @@ Deductible=Deductible from=from toward=toward Access=Access +HelpCopyToClipboard=Use Ctrl+C to copy to clipboard # Week day Monday=Monday diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index ee591bb4535..b34b784165a 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -658,6 +658,7 @@ Deductible=Déductible from=de toward=vers Access=Accès +HelpCopyToClipboard=Ctrl+C pour copier dans le presse-papier # Week day Monday=Lundi diff --git a/htdocs/margin/lib/margins.lib.php b/htdocs/margin/lib/margins.lib.php index c5237d219c5..bfa5d530e29 100644 --- a/htdocs/margin/lib/margins.lib.php +++ b/htdocs/margin/lib/margins.lib.php @@ -117,12 +117,18 @@ function getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localta // calcul pu_ht remisés $tabprice=calcul_price_total(1, $pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 'HT', 0, 0); // FIXME Parameter type is missing, i put 0 to avoid blocking error $pu_ht_remise = $tabprice[0]; + // calcul marge + if ($pu_ht_remise < 0) + $marge = -1 * (abs($pu_ht_remise) - $paht_ret); + else + $marge = $pu_ht_remise - $paht_ret; + // calcul taux marge if ($paht_ret != 0) - $marge_tx_ret = round((100 * ($pu_ht_remise - $paht_ret)) / $paht_ret, 3); + $marge_tx_ret = round((100 * $marge) / $paht_ret, 3); // calcul taux marque if ($pu_ht_remise != 0) - $marque_tx_ret = round((100 * ($pu_ht_remise - $paht_ret)) / $pu_ht_remise, 3); + $marque_tx_ret = round((100 * $marge) / $pu_ht_remise, 3); return array($paht_ret, $marge_tx_ret, $marque_tx_ret); }