diff --git a/.stickler.yml b/.stickler.yml index b68804448b2..4f7c7d06c27 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -7,4 +7,4 @@ linters: fixer: true fixers: - enable: true + enable: true \ No newline at end of file diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 8ba2f173ffd..0553fe3a1fa 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -111,6 +111,13 @@ class modFournisseur extends DolibarrModules $this->const[$r][4] = 0; $r++; + $this->const[$r][0] = "SUPPLIER_ORDER_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/supplier_orders"; + $this->const[$r][3] = ''; + $this->const[$r][4] = 0; + $r++; + // Boxes $this->boxes = array( 0=>array('file'=>'box_graph_invoices_supplier_permonth.php','enabledbydefaulton'=>'Home'), @@ -629,6 +636,24 @@ class modFournisseur extends DolibarrModules $this->remove($options); + //ODT template + $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt'; + $dirodt=DOL_DATA_ROOT.'/doctemplates/supplier_orders'; + $dest=$dirodt.'/template_supplier_order.odt'; + + if (file_exists($src) && ! file_exists($dest)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_mkdir($dirodt); + $result=dol_copy($src, $dest, 0, 0); + if ($result < 0) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest); + return 0; + } + } + $sql = array( "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[0][2])."' AND type = 'order_supplier' AND entity = ".$conf->entity, "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[0][2])."','order_supplier',".$conf->entity.")", diff --git a/htdocs/core/modules/supplier_order/pdf/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/pdf/doc_generic_supplier_order_odt.modules.php new file mode 100644 index 00000000000..d9e9112ec54 --- /dev/null +++ b/htdocs/core/modules/supplier_order/pdf/doc_generic_supplier_order_odt.modules.php @@ -0,0 +1,517 @@ + + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2014 Marcos García + * Copyright (C) 2016 Charlie Benke + * Copyright (C) 2018-2019 Philippe Grand + * Copyright (C) 2018 Frédéric France + * Copyright (C) 2019 Tim Otte + * + * 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/supplier_order/pdf/doc_generic_supplier_order_odt.modules.php + * \ingroup commande + * \brief File of class to build ODT documents for supplier orders + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders +{ + /** + * Issuer + * @var Societe + */ + public $issuer; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.5 = array(5, 5) + */ + public $phpmin = array(5, 5); + + /** + * @var string Dolibarr version of the loaded document + */ + public $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Load translation files required by the page + $langs->loadLangs(array("main","companies")); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'SUPPLIER_ORDER_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere issuer + $this->issuer=$mysoc; + if (! $this->issuer->country_code) $this->issuer->country_code=substr($langs->defaultlang, -2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + public function info($langs) + { + global $conf,$langs; + + // Load translation files required by the page + $langs->loadLangs(array("errors","companies")); + + $form = new Form($this->db); + + $texte = $this->description.".
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->SUPPLIER_ORDER_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0); + else + { + $tmpfiles=dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles, $tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1); + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + + // Scan directories + $nbofiles=count($listoffiles); + if (! empty($conf->global->COMMANDE_ADDON_PDF_ODT_PATH)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '; + //$texte.=$nbofiles?'':''; + $texte.=count($listoffiles); + //$texte.=$nbofiles?'':''; + $texte.=''; + } + + if ($nbofiles) + { + $texte.='
'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
'; + $texte.= '
'; + + return $texte; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build a document on disk using the generic odt module. + * + * @param Commande $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + public function write_file($object, $outputlangs, $srctemplatepath, $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $user,$langs,$conf,$mysoc,$hookmanager; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->loadLangs(array("main", "dict", "companies", "bills")); + + if ($conf->fournisseur->commande->dir_output) + { + $object->fetch_thirdparty(); + + if ($object->specimen) + { + $dir = $conf->fournisseur->commande->dir_output; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $objectrefsupplier = dol_sanitizeFileName($object->ref_supplier); + $dir = $conf->fournisseur->commande->dir_output . '/'. $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + if (! empty($conf->global->SUPPLIER_REF_IN_NAME)) $file = $dir . "/" . $objectref . ($objectrefsupplier?"_".$objectrefsupplier:"").".pdf"; + } + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i', '', $newfile); + $newfiletmp=preg_replace('/template_/i', '', $newfiletmp); + $newfiletmp=preg_replace('/modele_/i', '', $newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(), $format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->commande->dir_temp); + + + // If CUSTOMER contact defined on order, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external', 'CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + $contactobject=null; + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else { + $socobject = $object->thirdparty; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } + else + { + $socobject=$object->thirdparty; + } + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->issuer->name, + '__FROM_EMAIL__' => $this->issuer->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext=''; + $paramfreetext='ORDER_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext, $substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->fournisseur->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + dol_syslog($e->getMessage(), LOG_INFO); + } + + // Define substitution array + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $array_object_from_properties=$this->get_substitutionarray_each_var_object($object, $outputlangs); + $array_objet=$this->get_substitutionarray_object($object, $outputlangs); + $array_user=$this->get_substitutionarray_user($user, $outputlangs); + $array_soc=$this->get_substitutionarray_mysoc($mysoc, $outputlangs); + $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject, $outputlangs); + $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in object as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact && is_object($contactobject)) $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact'); + + $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + + // Call the ODTSubstitution hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/', $key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + // Replace tags of lines + try + { + $foundtagforlines = 1; + try { + $listlines = $odfHandler->setSegment('lines'); + } + catch(OdfException $e) + { + // We may arrive here if tags for lines not present into template + $foundtagforlines = 0; + dol_syslog($e->getMessage(), LOG_INFO); + } + if ($foundtagforlines) + { + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line, $outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + dol_syslog($e->getMessage(), LOG_INFO); + } + catch(SegmentException $e) + { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + + // Call the beforeODTSave hook + + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + } catch (Exception $e) { + $this->error=$e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + } + + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + $this->result = array('fullpath'=>$file); + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + return -1; + } +} diff --git a/htdocs/install/doctemplates/supplier_orders/index.html b/htdocs/install/doctemplates/supplier_orders/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/install/doctemplates/supplier_orders/template_supplier_order.odt b/htdocs/install/doctemplates/supplier_orders/template_supplier_order.odt new file mode 100644 index 00000000000..b9f5162316d Binary files /dev/null and b/htdocs/install/doctemplates/supplier_orders/template_supplier_order.odt differ diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 72f5780676b..9beff2dd38e 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -493,7 +493,7 @@ if (! defined('NOLOGIN')) } // Verification security graphic code - if (GETPOST("username", "alpha", 2) && ! empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA)) + if (GETPOST("username", "alpha", 2) && ! empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA) && ! isset($_SESSION['dol_bypass_antispam'])) { $sessionkey = 'dol_antispam_value'; $ok=(array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) == strtolower($_POST['code']))); diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 756bbde5b29..c0d415165c0 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -467,6 +467,59 @@ class Products extends DolibarrApi ); } + /** + * Get purchase prices for a product + * + * Return an array with product information. + * TODO implement getting a product by ref or by $ref_ext + * + * @param int $id ID of product + * @param string $ref Ref of element + * @param string $ref_ext Ref ext of element + * @param string $barcode Barcode of element + * @param int $includestockdata Load also information about stock (slower) + * @return array|mixed Data without useless information + * + * @url GET {id}/purchase_prices + * + * @throws 401 + * @throws 403 + * @throws 404 + * + */ + public function getPurchasePrices($id, $ref = '', $ref_ext = '', $barcode = '', $includestockdata = 0) + { + if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { + throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); + } + + $id = (empty($id)?0:$id); + + if(! DolibarrApiAccess::$user->rights->produit->lire) { + throw new RestException(403); + } + + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); + if(! $result ) { + throw new RestException(404, 'Product not found'); + } + + if(! DolibarrApi::_checkAccessToResource('product', $this->product->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if ($includestockdata) { + $this->product->load_stock(); + } + + if($result) { + $this->product = new ProductFournisseur($this->db); + $this->product->fetch($id, $ref); + $this->product->list_product_fournisseur_price($id, $sortfield, $sortorder, 0, 0); + } + + return $this->_cleanObjectDatas($this->product); + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 587d494a51f..cb56ff63cfc 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -196,7 +196,7 @@ if (empty($reshook)) $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Supplier")), null, 'errors'); } - if ($_POST["price"] < 0 || $_POST["price"] == '') + if (price2num($_POST["price"]) < 0 || $_POST["price"] == '') { if ($price_expression === '') // Return error of missing price only if price_expression not set { @@ -215,12 +215,12 @@ if (empty($reshook)) $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Currency")), null, 'errors'); } - if ($_POST["multicurrency_tx"] <= 0 || $_POST["multicurrency_tx"] == '') { + if (price2num($_POST["multicurrency_tx"]) <= 0 || $_POST["multicurrency_tx"] == '') { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("CurrencyRate")), null, 'errors'); } - if ($_POST["multicurrency_price"] < 0 || $_POST["multicurrency_price"] == '') { + if (price2num($_POST["multicurrency_price"]) < 0 || $_POST["multicurrency_price"] == '') { $error++; $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("PriceCurrency")), null, 'errors'); diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index e20b76b1349..3731cfe07fa 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1319,7 +1319,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' $arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); if (! in_array($cpt->currency, $arrayzerounitcurrency)) $amount = $cpt->amount / 100; else $amount = $cpt->amount; - print ''.$langs->trans("Available").''.price(amount, 0, '', 1, - 1, - 1, strtoupper($cpt->currency)).' '.$langs->trans("Currency".strtoupper($cpt->currency)).''; + print ''.$langs->trans("Available").''.price($amount, 0, '', 1, - 1, - 1, strtoupper($cpt->currency)).' '.$langs->trans("Currency".strtoupper($cpt->currency)).''; } } diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index d2e28572331..2e9029a45ab 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -273,7 +273,9 @@ if ($action == "addline") } if ($action == "freezone") { - $invoice->addline($desc, $number, 1, $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS, 0, 0, 0, 0, '', 0, 0, 0, '', 'TTC', $number, 0, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', null, 0); + $customer = new Societe($db); + $customer->fetch($invoice->socid); + $invoice->addline($desc, $number, 1, get_default_tva($mysoc, $customer), 0, 0, 0, 0, '', 0, 0, 0, '', 'TTC', $number, 0, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', null, 0); $invoice->fetch($placeid); }