diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index 31bcf1077e6..cf4f3832a1f 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -385,7 +385,7 @@ print ''."\n"; print ''.$langs->trans("AGENDA_DEFAULT_VIEW").''."\n"; print ' '."\n"; print ''."\n"; -$tmplist=array('show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_list'=>$langs->trans("ViewList"), 'show_peruser'=>$langs->trans("ViewPerUser")); +$tmplist=array('show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser")); print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $conf->global->AGENDA_DEFAULT_VIEW); print ''."\n"; diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 0e54d0cb8af..905d560f9c2 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -131,9 +131,9 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | { while (($file = readdir($handle))!==false) { - if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$reg)) + if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$regmod)) { - $module = strtolower($reg[1]); + $module = strtolower($regmod[1]); $moduledirforclass = getModuleDirForApiClass($module); $moduleforperm = $module; if ($module == 'propale') { $moduleforperm='propal'; } @@ -159,9 +159,9 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | if ($file_searched == 'api_access.class.php') continue; // Support of the deprecated API. - if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg)) + if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$regapi)) { - $classname = ucwords($reg[1]).'Api'; + $classname = ucwords($regapi[1]).'Api'; require_once $dir_part.$file_searched; if (class_exists($classname)) { @@ -173,9 +173,9 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); } } - elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg)) + elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi)) { - $classname = ucwords($reg[1]); + $classname = ucwords($regapi[1]); $classname = str_replace('_', '', $classname); require_once $dir_part.$file_searched; if (class_exists($classname)) @@ -206,7 +206,7 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | } // Call one APIs or one definition of an API -if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' && preg_match('/^\/resources.json\/(.+)$/', $reg[2], $regbis)))) +if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' && preg_match('/^\/resources.json\/(.+)$/', $reg[2], $regbis) && $regbis[1] != 'root'))) { $module = $reg[1]; if ($module == 'explorer') // If we call page to explore details of a service diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index b294f7c4aeb..d0e6cd94851 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -49,6 +49,7 @@ class Categorie extends CommonObject const TYPE_MEMBER = 3; // TODO Replace this value with 'member' const TYPE_CONTACT = 4; // TODO Replace this value with 'contact' const TYPE_USER = 4; // categorie contact and user are same ! TODO Replace this value with 'user' + const TYPE_ACCOUNT = 5; // TODO Replace this value with 'bank_account' const TYPE_PROJECT = 6; const TYPE_BANK_LINE = 'bank_line'; @@ -1174,11 +1175,11 @@ class Categorie extends CommonObject */ if($obj[0] > 0 && $obj[0] != $this->id) { - dol_syslog(get_class($this)."::already_exists category with name=".$this->label." exist rowid=".$obj[0]." current_id=".$this->id, LOG_DEBUG); + dol_syslog(get_class($this)."::already_exists category with name=".$this->label." and parent ".$this->fk_parent." exists: rowid=".$obj[0]." current_id=".$this->id, LOG_DEBUG); return 1; } } - dol_syslog(get_class($this)."::already_exists no category with same name=".$this->label." rowid=".$obj[0]." current_id=".$this->id, LOG_DEBUG); + dol_syslog(get_class($this)."::already_exists no category with same name=".$this->label." and same parent ".$this->fk_parent.": rowid=".$obj[0]." current_id=".$this->id, LOG_DEBUG); return 0; } else diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 13a7015059b..55f73575f78 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -59,9 +59,9 @@ else if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); $search_title=GETPOST('search_title','alpha'); -$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth'), GETPOST('dateselectday'), GETPOST('dateselectyear')); -$datestart=dol_mktime(0, 0, 0, GETPOST('datestartmonth'), GETPOST('datestartday'), GETPOST('datestartyear')); -$dateend=dol_mktime(0, 0, 0, GETPOST('dateendmonth'), GETPOST('dateendday'), GETPOST('dateendyear')); +$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); +$datestart=dol_mktime(0, 0, 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int')); +$dateend=dol_mktime(0, 0, 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int')); if ($status == '' && ! isset($_GET['status']) && ! isset($_POST['status'])) $status=(empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS)?'':$conf->global->AGENDA_DEFAULT_FILTER_STATUS); if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $action=(empty($conf->global->AGENDA_DEFAULT_VIEW)?'show_month':$conf->global->AGENDA_DEFAULT_VIEW); @@ -168,7 +168,7 @@ if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&con if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($actioncode != '') $param.="&actioncode=".$actioncode; if ($resourceid > 0) $param.="&resourceid=".$resourceid; -if ($status || isset($_GET['status']) || isset($_POST['status'])) $param.="&status=".$status; +if ($status != '' && $status > -1) $param.="&status=".$status; if ($filter) $param.="&filter=".$filter; if ($filtert) $param.="&filtert=".$filtert; if ($socid) $param.="&socid=".$socid; @@ -177,6 +177,13 @@ if ($pid) $param.="&projectid=".$pid; if ($type) $param.="&type=".$type; if ($usergroup) $param.="&usergroup=".$usergroup; if ($optioncss != '') $param.='&optioncss='.$optioncss; +if ($search_title != '') $param.='&search_title='.$search_title; +if (GETPOST('datestartday','int')) $param.='&datestartday='.GETPOST('datestartday','int'); +if (GETPOST('datestartmonth','int')) $param.='&datestartmonth='.GETPOST('datestartmonth','int'); +if (GETPOST('datestartyear','int')) $param.='&datestartyear='.GETPOST('datestartyear','int'); +if (GETPOST('dateendday','int')) $param.='&dateendday='.GETPOST('dateendday','int'); +if (GETPOST('dateendmonth','int')) $param.='&dateendmonth='.GETPOST('dateendmonth','int'); +if (GETPOST('dateendyear','int')) $param.='&dateendyear='.GETPOST('dateendyear','int'); $sql = "SELECT"; if ($usergroup > 0) $sql.=" DISTINCT"; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 0910fedcb9d..6fdbf9f7227 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1411,7 +1411,7 @@ class Commande extends CommonOrder if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); // Mise a jour informations denormalisees au niveau de la commande meme - $result=$this->update_price(1,'auto'); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + $result=$this->update_price(1,'auto',0,$mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. if ($result > 0) { $this->db->commit(); diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 6bc88e47490..52fb375000c 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -475,7 +475,13 @@ class FactureRec extends CommonInvoice { $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_rec WHERE rowid = ".$rowid; dol_syslog($sql); - if (! $this->db->query($sql)) + if ($this->db->query($sql)) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error=-3; + } + else { $this->error=$this->db->lasterror(); $error=-1; diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 00394b0e03f..1961cbb7af6 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -318,34 +318,6 @@ abstract class CommonDocGenerator return $array_other; } - - - - /** - * Define array with couple subtitution key => subtitution value - * - * @param Object $object Dolibarr Object - * @param Translate $outputlangs Language object for output - * @param boolean $recursive Want to fetch child array or child object - * @return array Array of substitution key->code - */ - function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true) { - $array_other = array(); - if(!empty($object)) { - foreach($object as $key => $value) { - if(!empty($value)) { - if(!is_array($value) && !is_object($value)) { - $array_other['object_'.$key] = $value; - } - if(is_array($value) && $recursive){ - $array_other['object_'.$key] = $this->get_substitutionarray_each_var_object($value,$outputlangs,false); - } - } - } - } - return $array_other; - } - /** @@ -410,10 +382,19 @@ abstract class CommonDocGenerator $array_key.'_total_ttc'=>price2num($object->total_ttc), $array_key.'_total_discount_ht' => price2num($object->getTotalDiscount()), + $array_key.'_multicurrency_code' => price2num($object->multicurrency_code), + $array_key.'_multicurrency_tx' => price2num($object->multicurrency_tx), + $array_key.'_multicurrency_total_ht' => price2num($object->multicurrency_total_ht), + $array_key.'_multicurrency_total_tva' => price2num($object->multicurrency_total_tva), + $array_key.'_multicurrency_total_ttc' => price2num($object->multicurrency_total_ttc), + $array_key.'_multicurrency_total_ht_locale' => price($object->multicurrency_total_ht, 0, $outputlangs), + $array_key.'_multicurrency_total_tva_locale' => price($object->multicurrency_total_tva, 0, $outputlangs), + $array_key.'_multicurrency_total_ttc_locale' => price($object->multicurrency_total_ttc, 0, $outputlangs), + $array_key.'_note_private'=>$object->note, $array_key.'_note_public'=>$object->note_public, $array_key.'_note'=>$object->note_public, // For backward compatibility - + // Payments $array_key.'_already_payed_locale'=>price($sumpayed, 0, $outputlangs), $array_key.'_already_payed'=>price2num($sumpayed), @@ -421,10 +402,10 @@ abstract class CommonDocGenerator $array_key.'_already_deposit'=>price2num($sumdeposit), $array_key.'_already_creditnote_locale'=>price($sumcreditnote, 0, $outputlangs), $array_key.'_already_creditnote'=>price2num($sumcreditnote), - + $array_key.'_already_payed_all_locale'=>price(price2num($sumpayed + $sumdeposit + $sumcreditnote, 'MT'), 0, $outputlangs), - $array_key.'already_payed_all'=> price2num(($sumpayed + $sumdeposit + $sumcreditnote), 'MT'), - + $array_key.'_already_payed_all'=> price2num(($sumpayed + $sumdeposit + $sumcreditnote), 'MT'), + // Remain to pay with all know infrmation (except open direct debit requests) $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT'), 0, $outputlangs), $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT') @@ -493,6 +474,16 @@ abstract class CommonDocGenerator 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'), 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs), 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'), + + 'line_multicurrency_code' => price2num($line->multicurrency_code), + 'line_multicurrency_subprice' => price2num($line->multicurrency_subprice), + 'line_multicurrency_total_ht' => price2num($line->multicurrency_total_ht), + 'line_multicurrency_total_tva' => price2num($line->multicurrency_total_tva), + 'line_multicurrency_total_ttc' => price2num($line->multicurrency_total_ttc), + 'line_multicurrency_subprice_locale' => price($line->multicurrency_subprice, 0, $outputlangs), + 'line_multicurrency_total_ht_locale' => price($line->multicurrency_total_ht, 0, $outputlangs), + 'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs), + 'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs), ); // Retrieve extrafields @@ -601,6 +592,33 @@ abstract class CommonDocGenerator ); } + + /** + * Define array with couple subtitution key => subtitution value + * + * @param Object $object Dolibarr Object + * @param Translate $outputlangs Language object for output + * @param boolean $recursive Want to fetch child array or child object + * @return array Array of substitution key->code + */ + function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true) { + $array_other = array(); + if(!empty($object)) { + foreach($object as $key => $value) { + if(!empty($value)) { + if(!is_array($value) && !is_object($value)) { + $array_other['object_'.$key] = $value; + } + if(is_array($value) && $recursive){ + $array_other['object_'.$key] = $this->get_substitutionarray_each_var_object($value,$outputlangs,false); + } + } + } + } + return $array_other; + } + + /** * Fill array with couple extrafield key => extrafield value * diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7babff42118..54388fdd701 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2463,12 +2463,12 @@ function dol_print_graph($htmlid,$width,$height,$data,$showlegend=0,$type='pie', * MAIN_DISABLE_TRUNC=1 can disable all truncings * * @param string $string String to truncate - * @param int $size Max string size visible. 0 for no limit. Final string size can be 1 more (if size was max+1) or 3 more (if we added ...) + * @param int $size Max string size visible (excluding ...). 0 for no limit. WARNING: Final string size can have 3 more chars (if we added ..., or if size was max+1 or max+2 or max+3 so it does not worse to replace with ...) * @param string $trunc Where to trunc: right, left, middle (size must be a 2 power), wrap * @param string $stringencoding Tell what is source string encoding * @param int $nodot Truncation do not add ... after truncation. So it's an exact truncation. * @param int $display Trunc is use to display and can be changed for small screen. TODO Remove this param (must be dealt with CSS) - * @return string Truncated string + * @return string Truncated string. WARNING: length is never higher than $size if $nodot is set, but can be 3 chars higher otherwise. */ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodot=0, $display=0) { @@ -2484,9 +2484,10 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo if ($trunc == 'right') { $newstring=dol_textishtml($string)?dol_string_nohtmltag($string,1):$string; - if (dol_strlen($newstring,$stringencoding) > ($size+($nodot?0:1))) + if (dol_strlen($newstring,$stringencoding) > ($size+($nodot?0:3))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ... return dol_substr($newstring,0,$size,$stringencoding).($nodot?'':'...'); else + //return 'u'.$size.'-'.$newstring.'-'.dol_strlen($newstring,$stringencoding).'-'.$string; return $string; } elseif ($trunc == 'middle') @@ -2504,7 +2505,7 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo elseif ($trunc == 'left') { $newstring=dol_textishtml($string)?dol_string_nohtmltag($string,1):$string; - if (dol_strlen($newstring,$stringencoding) > ($size+1)) + if (dol_strlen($newstring,$stringencoding) > ($size+($nodot?0:3))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ... return '...'.dol_substr($newstring,dol_strlen($newstring,$stringencoding) - $size,$size,$stringencoding); else return $string; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 09191609f00..32ad3283d44 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -1508,11 +1508,11 @@ class DolibarrModules // Can not be abstract, because we need to insta // Clean if (empty($visible)) $visible='0'; - if (empty($val)) $val=''; + if (empty($val) && $val != '0') $val=''; $sql = "SELECT count(*)"; $sql.= " FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'"; + $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($name)."'"; $sql.= " AND entity = ".$entity; $result=$this->db->query($sql); @@ -1526,7 +1526,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $sql.= " VALUES ("; $sql.= $this->db->encrypt($name,1); $sql.= ",'".$type."'"; - $sql.= ",".($val?$this->db->encrypt($val,1):"''"); + $sql.= ",".(($val != '')?$this->db->encrypt($val,1):"''"); $sql.= ",".($note?"'".$this->db->escape($note)."'":"null"); $sql.= ",'".$visible."'"; $sql.= ",".$entity; diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index cdcca71cb75..396ac54e9b5 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -146,7 +146,7 @@ class pdf_einstein extends ModelePDFCommandes } $this->posxdiscount=162; $this->postotalht=174; - if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxtva=$this->posxup; $this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this->page_largeur < 210) // To work with US executive format { diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 693dd2e412f..f087ad8c43e 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -132,7 +132,7 @@ class pdf_crabe extends ModelePDFFactures $this->posxdiscount=162; $this->posxprogress=126; // Only displayed for situation invoices $this->postotalht=174; - if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxtva=$this->posxup; $this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this->page_largeur < 210) // To work with US executive format { diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 972a75eecc8..3eb284ec7fc 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -120,7 +120,7 @@ class pdf_azur extends ModelePDFPropales } $this->posxdiscount=162; $this->postotalht=174; - if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxtva=$this->posxup; $this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this->page_largeur < 210) // To work with US executive format { diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index c5aabf27bf9..a7e8952c604 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -108,7 +108,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $this->posxqty=145; $this->posxdiscount=162; $this->postotalht=174; - if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxtva=$this->posxup; $this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this->page_largeur < 210) // To work with US executive format { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 159f76249df..f40273f7b3f 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -45,7 +45,7 @@ class CommandeFournisseur extends CommonOrder public $fk_element = 'fk_commande'; protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='order'; - + /** * {@inheritdoc} */ @@ -132,9 +132,9 @@ class CommandeFournisseur extends CommonOrder * Draft status */ const STATUS_DRAFT = 0; - - - + + + /** * Constructor * @@ -318,7 +318,7 @@ class CommandeFournisseur extends CommonOrder $line->subprice = $objp->subprice; $line->pu_ht = $objp->subprice; $line->remise_percent = $objp->remise_percent; - + $line->vat_src_code = $objp->vat_src_code; $line->total_ht = $objp->total_ht; $line->total_tva = $objp->total_tva; @@ -615,7 +615,7 @@ class CommandeFournisseur extends CommonOrder $picto='order'; $url = DOL_URL_ROOT.'/fourn/commande/card.php?id='.$this->id; - + $linkclose=''; if (empty($notooltip)) { @@ -627,7 +627,7 @@ class CommandeFournisseur extends CommonOrder $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose.=' class="classfortooltip"'; } - + $linkstart = ''; $linkend=''; @@ -1378,7 +1378,7 @@ class CommandeFournisseur extends CommonOrder } $desc=trim($desc); $ref_supplier=''; // Ref of supplier price when we add line - + // Check parameters if ($qty < 1 && ! $fk_product) { @@ -1402,7 +1402,7 @@ class CommandeFournisseur extends CommonOrder { $product_type = $prod->type; $label = $prod->label; - + // We use 'none' instead of $fourn_ref, because fourn_ref may not exists anymore. So we will take the first supplier price ok. // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', $this->fk_soc); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref/$this->fk_soc @@ -1422,7 +1422,7 @@ class CommandeFournisseur extends CommonOrder $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); $this->db->rollback(); dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price"); - //$pu = $prod->fourn_pu; // We do not overwrite unit price + //$pu = $prod->fourn_pu; // We do not overwrite unit price //$ref = $prod->ref_fourn; // We do not overwrite ref supplier price return -1; } @@ -1468,7 +1468,7 @@ class CommandeFournisseur extends CommonOrder $vat_src_code = $reg[1]; $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. } - + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx,$pu_ht_devise); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; @@ -1487,7 +1487,7 @@ class CommandeFournisseur extends CommonOrder $localtax2_type=$localtaxes_type[2]; $subprice = price2num($pu,'MU'); - + $rangmax = $this->line_max(); $rang = $rangmax + 1; @@ -1513,7 +1513,7 @@ class CommandeFournisseur extends CommonOrder $this->line->subprice=$pu_ht; $this->line->rang=$this->rang; $this->line->info_bits=$info_bits; - + $this->line->vat_src_code=$vat_src_code; $this->line->total_ht=$total_ht; $this->line->total_tva=$total_tva; @@ -1553,7 +1553,7 @@ class CommandeFournisseur extends CommonOrder if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); // Mise a jour informations denormalisees au niveau de la commande meme - $result=$this->update_price(1,'auto'); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + $result=$this->update_price(1,'auto',0,$this->thirdparty); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. if ($result > 0) { $this->db->commit(); @@ -2001,7 +2001,7 @@ class CommandeFournisseur extends CommonOrder $old_statut = $this->statut; $this->statut = $statut; $this->actionmsg2 = $comment; - + // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user); if ($result < 0) $error++; @@ -2334,7 +2334,7 @@ class CommandeFournisseur extends CommonOrder $vat_src_code = $reg[1]; $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. } - + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; @@ -2819,7 +2819,7 @@ class CommandeFournisseur extends CommonOrder return $text; } - + /** * Calc status regarding to dispatched stock * @@ -2828,7 +2828,7 @@ class CommandeFournisseur extends CommonOrder * @param string $comment Comment * @return int <0 if KO, 0 if not applicable, >0 if OK */ - public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') + public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') { global $conf, $langs; @@ -2845,14 +2845,14 @@ class CommandeFournisseur extends CommonOrder $filter['t.status']=1; } $ret=$supplierorderdispatch->fetchAll('','',0,0,$filter); - if ($ret<0) + if ($ret<0) { $this->error=$supplierorderdispatch->error; $this->errors=$supplierorderdispatch->errors; return $ret; - } - else + } + else { - if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines)>0) + if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines)>0) { //Build array with quantity deliverd by product foreach($supplierorderdispatch->lines as $line) { @@ -2861,12 +2861,12 @@ class CommandeFournisseur extends CommonOrder foreach($this->lines as $line) { $qtywished[$line->fk_product]+=$line->qty; } - + $date_liv = dol_now(); - + //Compare array $diff_array=array_diff_assoc($qtydelivered,$qtywished); - + if (count($diff_array)==0) //No diff => mean everythings is received { if ($closeopenorder) @@ -2888,8 +2888,8 @@ class CommandeFournisseur extends CommonOrder } return 4; } - } - else + } + else { //Diff => received partially $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' @@ -3014,12 +3014,12 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); $this->fk_unit = $objp->fk_unit; - + $this->multicurrency_subprice = $objp->multicurrency_subprice; $this->multicurrency_total_ht = $objp->multicurrency_total_ht; $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - + $this->db->free($result); return 1; } @@ -3208,7 +3208,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql.= ", subprice='".price2num($this->subprice)."'"; //$sql.= ",remise='".price2num($remise)."'"; $sql.= ", remise_percent='".price2num($this->remise_percent)."'"; - + $sql.= ", vat_src_code = '".(empty($this->vat_src_code)?'':$this->vat_src_code)."'"; $sql.= ", tva_tx='".price2num($this->tva_tx)."'"; $sql.= ", localtax1_tx='".price2num($this->total_localtax1)."'"; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 5c8a41a0466..0f63a02008f 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1430,7 +1430,7 @@ class FactureFournisseur extends CommonInvoice if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); // Mise a jour informations denormalisees au niveau de la facture meme - $result=$this->update_price(1,'auto',0,$mysoc); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. + $result=$this->update_price(1,'auto',0,$this->thirdparty); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. if ($result > 0) { $this->db->commit(); diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 4e2e2acf378..38a40315985 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -75,6 +75,9 @@ InterventionSentByEMail=Intervention %s sent by EMail ProposalDeleted=Proposal deleted OrderDeleted=Order deleted InvoiceDeleted=Invoice deleted +PRODUCT_CREATEInDolibarr=Product %s created +PRODUCT_MODIFYInDolibarr=Product %s modified +PRODUCT_DELETEInDolibarr=Product %s deleted ##### End agenda events ##### AgendaModelModule=Document templates for event DateActionStart=Start date diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index a35342f2af9..8b1c0df7f40 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -358,6 +358,7 @@ TotalLT1ES=Total RE TotalLT2ES=Total IRPF HT=Net of tax TTC=Inc. tax +INCT=Inc. all taxes VAT=Sales tax VATs=Sales taxes LT1ES=RE diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 8c86f544dba..e296d44bd33 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -33,6 +33,7 @@ */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_expression.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php'; @@ -759,12 +760,8 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) print ''.$langs->trans("MinPrice").''; print ''; - $var=True; - for($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - $var = ! $var; - print ''; // Label of price @@ -1244,11 +1241,8 @@ if ($action == 'edit_price' && $object->getRights()->creer) print ''; - $var = false; for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { - $var = !$var; - print ''; print ''; print $form->textwithpicto($langs->trans('SellingPrice') . ' ' . $i, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); @@ -1389,13 +1383,12 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ $notfirstlineforlevel=array(); - $var = True; $i = 0; while ($i < $num) { $objp = $db->fetch_object($result); - $var = ! $var; - print ''; + + print ''; // Date print "" . dol_print_date($db->jdate($objp->dp), "dayhour") . ""; @@ -1440,7 +1433,9 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ print ''; } } + print '' . ($objp->price_base_type != 'TTC' ? price($objp->price_min) : '') . ''; + print '' . ($objp->price_base_type == 'TTC' ? price($objp->price_min_ttc) : '') . ''; // User @@ -1611,9 +1606,12 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; + + dol_fiche_head(); + print ''; print ''; - print ''; + print ''; $staticsoc = new Societe($db); $staticsoc->fetch($prodcustprice->fk_soc); print ""; @@ -1625,7 +1623,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // Price base - print ''; print ''; // Price - print ''; // Update all child soc - print ''; print '
' . $langs->trans('ThirdParty') . '' . $langs->trans('ThirdParty') . '" . $staticsoc->getNomUrl(1) . "
'; + print '
'; print $langs->trans('PriceBase'); print ''; @@ -1634,7 +1632,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '
'; + print '
'; $text = $langs->trans('SellingPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; @@ -1663,7 +1661,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '
'; + print '
'; print $langs->trans('ForceUpdateChildPriceSoc'); print ''; @@ -1673,7 +1671,9 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '
'; - print '
'; + dol_fiche_end(); + + print '
'; print ''; print '     '; print ''; @@ -1683,7 +1683,10 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) } elseif ($action == 'showlog_customer_price') { - $filter = array('t.fk_product' => $object->id,'t.fk_soc' => GETPOST('socid', 'int')); + // List of all log of prices by customers + print ''."\n"; + + $filter = array('t.fk_product' => $object->id,'t.fk_soc' => GETPOST('socid', 'int')); // Count total nb of records $nbtotalofrecords = ''; @@ -1710,7 +1713,6 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) if (count($prodcustprice->lines) > 0) { - print '
'; print ''; @@ -1723,31 +1725,53 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '' . $langs->trans("VATRate") . ''; print '' . $langs->trans("HT") . ''; print '' . $langs->trans("TTC") . ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print '' . $langs->trans("INCT") . ''; print '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . ''; print '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . ''; print '' . $langs->trans("ChangedBy") . ''; print ' '; print ''; - $var = True; - foreach ($prodcustprice->lines as $line) { - $var = ! $var; - print ''; - // Date - $staticsoc = new Societe($db); - $staticsoc->fetch($line->fk_soc); - - print "" . $staticsoc->getNomUrl(1) . ""; - print "" . dol_print_date($line->datec, "dayhour") . ""; + // Date + $staticsoc = new Societe($db); + $staticsoc->fetch($line->fk_soc); $tva_tx = $line->default_vat_code ? $line->tva_tx.' ('.$line->default_vat_code.')' : $line->tva_tx; - print '' . $langs->trans($line->price_base_type) . ""; + // Line for default price + if ($line->price_base_type=='HT') + { + $pu=$line->price; + } + else + { + $pu=$line->price_ttc; + } + + // Local tax is not saved into table of product. We use value linked to VAT code. + $localtaxarray=getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code?' ('.$line->default_vat_code.')':''), 0, $staticsoc, $mysoc); + // Define part of HT, VAT, TTC + $resultarray=calcul_price_total(1, $pu, 0, $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly, $object->type, $mysoc, $localtaxarray); + // Calcul du total ht sans remise + $total_ht = $resultarray[0]; + $total_vat = $resultarray[1]; + $total_localtax1 = $resultarray[9]; + $total_localtax2 = $resultarray[10]; + $total_ttc = $resultarray[2]; + + print ''; + + print "" . $staticsoc->getNomUrl(1) . ""; + print "" . dol_print_date($line->datec, "dayhour") . ""; + print '' . $langs->trans($line->price_base_type) . ""; print '' . vatrate($tva_tx, true, $line->recuperableonly) . ""; print '' . price($line->price) . ""; print '' . price($line->price_ttc) . ""; + + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print '' . price($resultarray[2]) . ''; + print '' . price($line->price_min) . ''; print '' . price($line->price_min_ttc) . ''; @@ -1757,6 +1781,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print $userstatic->getLoginUrl(1); print ''; + print ''; } print ""; } else { @@ -1766,7 +1791,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) else if ($action != 'showlog_default_price' && $action != 'edit_price') { // List of all prices by customers - print ''."\n"; + print ''."\n"; // Count total nb of records $nbtotalofrecords = ''; @@ -1788,24 +1813,14 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (count($prodcustprice->lines) > 0 || $search_soc) { + $colspan=8; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++; + print ''; print ''; - print ''; + print ''; // Print the search button print ''; } - $var = False; - + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + print ''; + print ''; + print ''; + print ''; + print ''; // Line for default price + if ($object->price_base_type=='HT') + { + $pu=$object->price; + } + else + { + $pu=$object->price_ttc; + } + + // Local tax is not saved into table of product. We use value linked to VAT code. + $localtaxarray=getLocalTaxesFromRate($object->tva_tx.($object->default_vat_code?' ('.$object->default_vat_code.')':''), 0, $mysoc, $mysoc); + // Define part of HT, VAT, TTC + $resultarray=calcul_price_total(1, $pu, 0, $object->tva_tx, 1, 1, 0, $object->price_base_type, $object->recuperableonly, $object->type, $mysoc, $localtaxarray); + // Calcul du total ht sans remise + $total_ht = $resultarray[0]; + $total_vat = $resultarray[1]; + $total_localtax1 = $resultarray[9]; + $total_localtax2 = $resultarray[10]; + $total_ttc = $resultarray[2]; + print ''; print ""; print ""; @@ -1827,8 +1873,12 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print vatrate($object->tva_tx, true, $object->recuperableonly); print $object->default_vat_code?' ('.$object->default_vat_code.')':''; print ""; + print '"; print '"; + + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + print ''; print ''; print ''; - // Date $staticsoc = new Societe($db); $staticsoc->fetch($line->fk_soc); $tva_tx = $line->default_vat_code ? $line->tva_tx.' ('.$line->default_vat_code.')' : $line->tva_tx; + // Line for default price + if ($line->price_base_type=='HT') + { + $pu=$line->price; + } + else + { + $pu=$line->price_ttc; + } + + // Local tax is not saved into table of product. We use value linked to VAT code. + $localtaxarray=getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code?' ('.$line->default_vat_code.')':''), 0, $staticsoc, $mysoc); + // Define part of HT, VAT, TTC + $resultarray=calcul_price_total(1, $pu, 0, $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly, $object->type, $mysoc, $localtaxarray); + // Calcul du total ht sans remise + $total_ht = $resultarray[0]; + $total_vat = $resultarray[1]; + $total_localtax1 = $resultarray[9]; + $total_localtax2 = $resultarray[10]; + $total_ttc = $resultarray[2]; + + print ''; + print ""; print ""; @@ -1871,6 +1939,9 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '"; print '"; print '"; + + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + print ''; print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ce92103f927..1605e7281b8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -882,8 +882,6 @@ class Societe extends CommonObject $sql .= ', multicurrency_code = \''.$this->db->escape($this->multicurrency_code)."'"; $sql .= " WHERE rowid = '" . $id ."'"; - - dol_syslog(get_class($this)."::Update", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -978,11 +976,12 @@ class Societe extends CommonObject { // Doublon $this->error = $langs->trans("ErrorDuplicateField"); - $result = -1; + $result = -1; } else { - $result = -2; + $this->error = $this->db->lasterror(); + $result = -2; } $this->db->rollback(); return $result; diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index 05e39ffc576..5146e3ad6a5 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -21,10 +21,11 @@ */ /** - * \file htdocs/societe/price.php + * \file htdocs/societe/price.php * \ingroup product - * \brief Page to show product prices by customer + * \brief Page to show product prices by customer */ + require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; @@ -42,7 +43,8 @@ $langs->load("companies"); $langs->load("bills"); $action = GETPOST('action', 'alpha'); -$search_prod = GETPOST('search_prod'); +$search_prod = GETPOST('search_prod','alpha'); +$cancel = GETPOST('cancel','alpha'); // Security check $socid = GETPOST('socid', 'int')?GETPOST('socid', 'int'):GETPOST('id', 'int'); @@ -71,36 +73,72 @@ if (empty($reshook)) { $search_prod = ''; } - - if ($action == 'add_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) { - + + if ($action == 'add_customer_price_confirm' && ! $cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { + $update_child_soc = GETPOST('updatechildprice'); - + // add price by customer $prodcustprice->fk_soc = $socid; $prodcustprice->fk_product = GETPOST('prodid', 'int'); $prodcustprice->price = price2num(GETPOST("price"), 'MU'); $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); - $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); - + + $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' + + // We must define tva_tx, npr and local taxes + $vatratecode = ''; + $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; + $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; + // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + // We look into database using code (we can't use get_localtax() because it depends on buyer that is not known). Same in update price. + $vatratecode=$reg[1]; + // Get record from code + $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; + $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; + $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.code ='".$vatratecode."'"; + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + $npr = $obj->recuperableonly; + $localtax1 = $obj->localtax1; + $localtax2 = $obj->localtax2; + $localtax1_type = $obj->localtax1_type; + $localtax2_type = $obj->localtax2_type; + } + } + + $prodcustprice->default_vat_code = $vatratecode; + $prodcustprice->tva_tx = $tva_tx; + $prodcustprice->recuperableonly = $npr; + $prodcustprice->localtax1_tx = $localtax1; + $prodcustprice->localtax2_tx = $localtax2; + $prodcustprice->localtax1_type = $localtax1_type; + $prodcustprice->localtax2_type = $localtax2_type; + $result = $prodcustprice->create($user, 0, $update_child_soc); - + if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } else { setEventMessages($langs->trans('Save'), null, 'mesgs'); } - + $action = ''; } - + if ($action == 'delete_customer_price' && ($user->rights->produit->creer || $user->rights->service->creer)) { // Delete price by customer $prodcustprice->id = GETPOST('lineid'); $result = $prodcustprice->delete($user); - + if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'mesgs'); } else { @@ -108,27 +146,27 @@ if (empty($reshook)) } $action = ''; } - + if ($action == 'update_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) { - + $prodcustprice->fetch(GETPOST('lineid', 'int')); - + $update_child_soc = GETPOST('updatechildprice'); - + // update price by customer $prodcustprice->price = price2num(GETPOST("price"), 'MU'); $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); - + $result = $prodcustprice->update($user, 0, $update_child_soc); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } else { setEventMessages($langs->trans('Save'), null, 'mesgs'); } - + $action = ''; } } @@ -154,7 +192,7 @@ dol_fiche_head($head, 'price', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom'); - + print '
'; print '
'; @@ -239,7 +277,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { // VAT print '
'; // Price base @@ -299,7 +337,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print load_fiche_titre($langs->trans('PriceByCustomer')); $result = $prodcustprice->fetch(GETPOST('lineid', 'int')); - if ($result < 0) + if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } @@ -374,6 +412,8 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print '
'; } elseif ($action == 'showlog_customer_price') { + print ''."\n"; + $filter = array ( 't.fk_product' => GETPOST('prodid', 'int'),'t.fk_soc' => $socid ); @@ -385,7 +425,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { } $result = $prodcustprice->fetch_all_log($sortorder, $sortfield, $conf->liste_limit, $offset, $filter); - if ($result < 0) + if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } @@ -440,8 +480,8 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; } print "
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
  '; $searchpicto=$form->showFilterAndCheckAddButtons(0); @@ -1814,10 +1829,41 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
" . $langs->trans("Default") . "" . "' . price($object->price) . "' . price($object->price_ttc) . "' . price($resultarray[2]) . '' . price($object->price_min) . '' . price($object->price_min_ttc) . ''; @@ -1851,19 +1901,37 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) if (count($prodcustprice->lines) > 0) { - $var = false; foreach ($prodcustprice->lines as $line) { - $var = ! $var; - - print '
" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . vatrate($tva_tx, true, $line->recuperableonly) . "' . price($line->price) . "' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_min) . '' . price($line->price_min_ttc) . '
' . $langs->trans("VATRate") . ''; - print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr); + print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, '', false, 1); print '
"; - } - else + } + else { print $langs->trans('None'); } @@ -449,8 +489,8 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print "\n" . '
' . "\n"; print ''; print "\n

\n"; - } - else + } + else { // View mode @@ -466,30 +506,32 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; } print "\n
\n"; - - + + // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $nbtotalofrecords = $prodcustprice->fetch_all('', '', 0, 0, $filter); } - + $result = $prodcustprice->fetch_all($sortorder, $sortfield, $conf->liste_limit, $offset, $filter); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } - + $option = '&search_prod=' . $search_prod . '&id=' . $object->id; - - print_barre_liste($langs->trans('PriceForEachProduct'), $page, $_SERVEUR['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords, ''); - + + print ''."\n"; + + print_barre_liste($langs->trans('PriceForEachProduct'), $page, $_SERVEUR['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords, ''); + print '
'; print ''; - + print ''; - + print ''; print ''; print ''; @@ -502,12 +544,12 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''; print ''; - + if (count($prodcustprice->lines) > 0 || $search_prod) { print ''; - print ''; - print ''; + print ''; + print ''; // Print the search button print ''; print ''; } - + if (count($prodcustprice->lines) > 0) { $var = False; - + foreach ($prodcustprice->lines as $line) { print ""; - + $staticprod = new Product($db); $staticprod->fetch($line->fk_product); - + print ""; print ""; - + print '"; - print '"; + print '"; print '"; print '"; print ''; print ''; - + // User $userstatic = new User($db); $userstatic->fetch($line->fk_user); print ''; - + // Action if ($user->rights->produit->creer || $user->rights->service->creer) { @@ -561,21 +603,21 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''; } - + print "\n"; } } else { $colspan=9; - if ($user->rights->produit->supprimer || $user->rights->service->supprimer) $colspan+=1; + if ($user->rights->produit->supprimer || $user->rights->service->supprimer) $colspan+=1; print ''; } - + print "
' . $langs->trans("Product") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("ChangedBy") . ' 
  '; $searchpicto=$form->showFilterAndCheckAddButtons(0); @@ -515,35 +557,35 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print '
" . $staticprod->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($line->tva_tx, true, $line->recuperableonly) . "' . vatrate($line->tva_tx.($line->default_vat_code?' ('.$line->default_vat_code.')':''), true, $line->recuperableonly) . "' . price($line->price) . "' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . ''; print $userstatic->getLoginUrl(1); print '
' . $langs->trans('None') . '
"; - + print "
"; - + } } diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index bf0d42b889a..0c8410213af 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -506,7 +506,7 @@ class SupplierProposal extends CommonObject if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); // Mise a jour informations denormalisees au niveau de la propale meme - $result=$this->update_price(1,'auto'); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + $result=$this->update_price(1,'auto',0,$this->thirdparty); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. if ($result > 0) { $this->db->commit(); diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 4e98ce0b3bc..873a17758c8 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -132,21 +132,21 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase /*$tmp=dol_buildpath('/google/oauth2callback.php', 0); var_dump($tmp); */ - + /*$tmp=dol_buildpath('/google/oauth2callback.php', 1); var_dump($tmp); */ - + $result=dol_buildpath('/google/oauth2callback.php', 2); print __METHOD__." result=".$result."\n"; $this->assertStringStartsWith('http', $result); - + $result=dol_buildpath('/google/oauth2callback.php', 3); print __METHOD__." result=".$result."\n"; $this->assertStringStartsWith('http', $result); } - - + + /** * testGetBrowserInfo * @@ -512,32 +512,48 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase // Default trunc (will add ... if truncation truncation or keep last char if only one char) $input="éeéeéeàa"; $after=dol_trunc($input,3); - $this->assertEquals("éeé...",$after); + $this->assertEquals("éeé...",$after,'Test A1'); $after=dol_trunc($input,2); - $this->assertEquals("ée...",$after); + $this->assertEquals("ée...",$after,'Test A2'); + $after=dol_trunc($input,1); + $this->assertEquals("é...",$after,'Test A3'); + $input="éeéeé"; + $after=dol_trunc($input,3); + $this->assertEquals("éeéeé",$after,'Test B1'); + $after=dol_trunc($input,2); + $this->assertEquals("éeéeé",$after,'Test B2'); + $after=dol_trunc($input,1); + $this->assertEquals("é...",$after,'Test B3'); + $input="éeée"; + $after=dol_trunc($input,3); + $this->assertEquals("éeée",$after,'Test C1'); + $after=dol_trunc($input,2); + $this->assertEquals("éeée",$after,'Test C2'); + $after=dol_trunc($input,1); + $this->assertEquals("éeée",$after,'Test C3'); $input="éeé"; $after=dol_trunc($input,3); - $this->assertEquals("éeé",$after); + $this->assertEquals("éeé",$after,'Test C'); $after=dol_trunc($input,2); - $this->assertEquals("éeé",$after); + $this->assertEquals("éeé",$after,'Test D'); $after=dol_trunc($input,1); - $this->assertEquals("é...",$after); + $this->assertEquals("éeé",$after,'Test E'); // Trunc with no ... $input="éeéeéeàa"; $after=dol_trunc($input,3,'right','UTF-8',1); - $this->assertEquals("éeé",$after); + $this->assertEquals("éeé",$after,'Test F'); $after=dol_trunc($input,2,'right','UTF-8',1); - $this->assertEquals("ée",$after); + $this->assertEquals("ée",$after,'Test G'); $input="éeé"; $after=dol_trunc($input,3,'right','UTF-8',1); - $this->assertEquals("éeé",$after); + $this->assertEquals("éeé",$after,'Test H'); $after=dol_trunc($input,2,'right','UTF-8',1); - $this->assertEquals("ée",$after); + $this->assertEquals("ée",$after,'Test I'); $after=dol_trunc($input,1,'right','UTF-8',1); - $this->assertEquals("é",$after); + $this->assertEquals("é",$after,'Test J'); $input="éeéeéeàa"; $after=dol_trunc($input,4,'middle'); - $this->assertEquals("ée...àa",$after); + $this->assertEquals("ée...àa",$after,'Test K'); return true; } @@ -668,7 +684,7 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase $this->assertEquals("21 jump street\nMyTown, MyState, 99999",$address); } - + /** * testDolFormatAddress * @@ -681,18 +697,18 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + $object=new Societe($db); $object->initAsSpecimen(); - + $object->country_code='FR'; $phone=dol_print_phone('1234567890', $object->country_code); $this->assertEquals('12 34 56 78 90', $phone, 'Phone for FR 1'); - + $object->country_code='FR'; $phone=dol_print_phone('1234567890', $object->country_code, 0, 0, 0, ''); $this->assertEquals('1234567890', $phone, 'Phone for FR 2'); - + $object->country_code='FR'; $phone=dol_print_phone('1234567890', $object->country_code, 0, 0, 0, ' '); $this->assertEquals('12 34 56 78 90', $phone, 'Phone for FR 3'); @@ -700,10 +716,10 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase $object->country_code='CA'; $phone=dol_print_phone('1234567890', $object->country_code, 0, 0, 0, ' '); $this->assertEquals('(123) 456-7890', $phone, 'Phone for CA 1'); - + } - - + + /** * testImgPicto * @@ -1053,5 +1069,5 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase return true; } - + }