From 5cce8c45e3895336a0051b72f439d98e6e2c1302 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Fri, 5 Dec 2014 18:23:54 +0100 Subject: [PATCH 01/61] WIP PrintIPP --- htdocs/comm/propal.php | 2 +- htdocs/commande/card.php | 2 +- htdocs/compta/facture.php | 2 +- htdocs/core/actions_printing.inc.php | 58 +++++++ htdocs/core/actions_printipp.inc.php | 45 ----- htdocs/core/class/dolprintipp.class.php | 2 +- htdocs/core/class/html.formfile.class.php | 2 +- htdocs/core/modules/modPrintIPP.class.php | 19 ++- htdocs/core/modules/modPrinting.class.php | 155 ++++++++++++++++++ ...nterface_60_modPrinting_Printing.class.php | 71 ++++++++ htdocs/printing/admin/index.html | 0 htdocs/printing/admin/printing.php | 127 ++++++++++++++ htdocs/printing/index.php | 38 +++++ 13 files changed, 464 insertions(+), 59 deletions(-) create mode 100644 htdocs/core/actions_printing.inc.php delete mode 100644 htdocs/core/actions_printipp.inc.php create mode 100644 htdocs/core/modules/modPrinting.class.php create mode 100644 htdocs/core/triggers/interface_60_modPrinting_Printing.class.php create mode 100644 htdocs/printing/admin/index.html create mode 100644 htdocs/printing/admin/printing.php create mode 100644 htdocs/printing/index.php diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index aa75945f0ea..908a8d4c8ad 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -553,7 +553,7 @@ else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST( } } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; /* diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 309b0c35e1a..a9a8800ede1 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1142,7 +1142,7 @@ else if ($action == 'update_extras') { $action = 'edit_extras'; } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; /* diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index be6ad58764a..4e79e710321 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1615,7 +1615,7 @@ else if ($action == 'remove_file') { } } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php new file mode 100644 index 00000000000..f864524fce1 --- /dev/null +++ b/htdocs/core/actions_printing.inc.php @@ -0,0 +1,58 @@ + + * Copyright (C) 2014 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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/actions_printing.inc.php + * \brief Code for actions print_file to print file with calling trigger + */ + + +// $action must be defined +// $db, $user, $conf, $langs must be defined +// Filename to print must be provided into 'file' parameter + +// Print file +if ($action == 'print_file' and $user->rights->printing->read) +{ + $langs->load("printing"); + //require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; + //$printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); + //$result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); + // Call trigger to Print Doc + //$actiontypecode='AC_PRINT'; + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $trigger_name='PRINT_DOCPDF'; + $printing->file = GETPOST('file', 'alpha'); + $printing->printer = GETPOST('printer', 'alpha'); + //print print_r($printing, true); + + $result=$interface->run_triggers($trigger_name,$printing,$user,$langs,$conf); + if ($result < 0) { + setEventMessage($interface->errors, 'errors'); + } + if ($result == 0) { + setEventMessage($langs->trans("NoModuleFound")); + } + + if ($result>0) { + setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file')))); + } + $action = ''; +} diff --git a/htdocs/core/actions_printipp.inc.php b/htdocs/core/actions_printipp.inc.php deleted file mode 100644 index 3c18faa813b..00000000000 --- a/htdocs/core/actions_printipp.inc.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * 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/actions_printipp.inc.php - * \brief Code for actions print_file to print file using ipp - */ - - -// $action must be defined -// $db, $user, $conf, $langs must be defined -// Filename to print must be provided into 'file' parameter - -// Print file -if ($action == 'print_file' and $user->rights->printipp->read) -{ - $langs->load("printipp"); - require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - $result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - if ($result) - { - setEventMessage($result,'warnings'); - } - else - { - setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file')))); - } - $action = ''; -} diff --git a/htdocs/core/class/dolprintipp.class.php b/htdocs/core/class/dolprintipp.class.php index 71ee2a1be37..272d46ec745 100644 --- a/htdocs/core/class/dolprintipp.class.php +++ b/htdocs/core/class/dolprintipp.class.php @@ -28,7 +28,7 @@ class dolprintIPP { var $host; var $port; - var $userid; /* user login */ + var $userid; /* user login */ var $user; var $password; var $error; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 9a419e53d89..d2183c582cd 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -274,7 +274,7 @@ class FormFile $printer=0; if (in_array($modulepart,array('facture','propal','proposal','order','commande'))) // This feature is implemented only for such elements { - $printer = (!empty($user->rights->printipp->read) && !empty($conf->printipp->enabled))?true:false; + $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false; } $hookmanager->initHooks(array('formfile')); diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrintIPP.class.php index 3cdcd6cdfa6..1f3d0a71a7a 100644 --- a/htdocs/core/modules/modPrintIPP.class.php +++ b/htdocs/core/modules/modPrintIPP.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2014 Frederic France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,9 +23,9 @@ /** * \file htdocs/core/modules/modPrintIPP.class.php * \ingroup printipp - * \brief Fichier de description et activation du module OSCommerce2 + * \brief Fichier de description et activation du module PrintIPP */ -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php"); +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; @@ -37,9 +38,9 @@ class modPrintIPP extends DolibarrModules /** - * Constructor + * Constructor * - * @param DoliDB $db Database handler + * @param DoliDB $db Database handler */ function __construct($db) { @@ -68,10 +69,10 @@ class modPrintIPP extends DolibarrModules // Dependances $this->hidden = (! empty($_SERVER["WINDIR"])); - $this->depends = array(); + $this->depends = array('printing'); $this->requiredby = array(); - $this->phpmin = array(5,1); // Minimum version of PHP required by module - $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module + $this->phpmin = array(5,1); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module $this->conflictwith = array(); $this->langfiles = array("printipp"); @@ -142,8 +143,8 @@ class modPrintIPP extends DolibarrModules * Remove from database constants, boxes and permissions from Dolibarr database. * Data directories are not deleted * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO */ function remove($options='') { diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php new file mode 100644 index 00000000000..144b023bdc8 --- /dev/null +++ b/htdocs/core/modules/modPrinting.class.php @@ -0,0 +1,155 @@ + + * Copyright (C) 2014 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 . + */ + +/** \defgroup printing Module printing + * \brief Module for activation of printing icon + */ + +/** + * \file htdocs/core/modules/modPrinting.class.php + * \ingroup printing + * \brief Fichier de description et activation du module Printing + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + + +/** + * \class modPrinting + * \brief Classe de description et activation du module Printing + */ +class modPrinting extends DolibarrModules +{ + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db ; + $this->numero = 112000; + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "other"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + $this->description = "Enable Printing System."; + $this->version = 'experimental'; // 'development' or 'experimental' or 'dolibarr' or version + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 1; + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto = 'technic'; + + // Data directories to create when module is enabled. + $this->dirs = array(); + + // Config pages + $this->config_page_url = array("printing.php@printing"); + + // Dependances + $this->hidden = (! empty($_SERVER["WINDIR"])); + $this->depends = array(); + $this->requiredby = array(); + $this->phpmin = array(5,1); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module + $this->conflictwith = array(); + $this->langfiles = array("printing"); + + // Constantes + $this->const = array(); + + // Boxes + $this->boxes = array(); + + // Permissions + $this->rights = array(); + $this->rights_class = 'printing'; + + $r=0; + // $this->rights[$r][0] Id permission (unique tous modules confondus) + // $this->rights[$r][1] Libelle par defaut si traduction de cle "PermissionXXX" non trouvee (XXX = Id permission) + // $this->rights[$r][2] Non utilise + // $this->rights[$r][3] 1=Permis par defaut, 0=Non permis par defaut + // $this->rights[$r][4] Niveau 1 pour nommer permission dans code + // $this->rights[$r][5] Niveau 2 pour nommer permission dans code + + $r++; + $this->rights[$r][0] = 112001; + $this->rights[$r][1] = 'Printing'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 1; + $this->rights[$r][4] = 'read'; + + // Main menu entries + $this->menus = array(); // List of menus to add + $r=0; + + // This is to declare the Top Menu entry: + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Put 0 if this is a top menu + 'type'=>'left', // This is a Top menu entry + 'titre'=>'Printing', + 'mainmenu'=>'printing', + 'url'=>'/printing/index.php', + 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>300, + 'enabled'=>'$conf->printing->enabled && $leftmenu==\'modulesadmintools\'', + 'perms'=>'$user->rights->printing->read', // Use 'perms'=>'1' if you want your menu with no permission rules + 'target'=>'', + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both + + $r++; + + + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + $sql = array(); + + return $this->_init($sql, $options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') + { + $sql = array(); + + return $this->_remove($sql, $options); + } + +} diff --git a/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php b/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php new file mode 100644 index 00000000000..b02b16f4796 --- /dev/null +++ b/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php @@ -0,0 +1,71 @@ + + * Copyright (C) 2005-2014 Regis Houssin + * Copyright (C) 2014 Marcos García + * + * 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 . + */ + +/** + * \file htdocs/core/triggers/interface_60_modPrinting_Printing.class.php + * \ingroup printing + * \brief Trigger call by printing to print with PrintIPP + * \remarks + */ +require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; + + +/** + * Class of triggers for printing + */ +class InterfacePrinting extends DolibarrTriggers +{ + + public $family = 'printing'; + public $picto = 'technic'; + public $description = "Triggers of this module is used for printing via PrintIPP."; + public $version = self::VERSION_DOLIBARR; + + /** + * Function called when a Dolibarrr business event is done. + * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared) + * + * @param string $action Event action code + * @param Object $object Object + * @param User $user Object user + * @param Translate $langs Object langs + * @param conf $conf Object conf + * @return int <0 if KO, 0 if no triggered ran, >0 if OK + */ + public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) + { + global $db; + // Put here code you want to execute when a Dolibarr business events occurs. + // Data and type of action are stored into $object and $action + + // Actions + + if ($action=='PRINT_DOCPDF') { + require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; + $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); + $result = $printer->print_file($object->file, $object->printer); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + //$this->errors[]='test'; + //return -1; + return 1; + } + return 0; + } + +} diff --git a/htdocs/printing/admin/index.html b/htdocs/printing/admin/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php new file mode 100644 index 00000000000..29bd8787fa0 --- /dev/null +++ b/htdocs/printing/admin/printing.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2014 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 . + */ + +/** + * \file htdocs/printing/admin/printing.php + * \ingroup printing + * \brief Page to setup printing module + */ + +require '../../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; +//require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; +//require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php'; + +$langs->load("admin"); +$langs->load("printing"); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$mode = GETPOST('mode','alpha'); +$value = GETPOST('value','alpha'); + +if (!$mode) $mode='config'; + +/* + * Action + */ + + + +/* + * View + */ + +$form = new Form($db); + +llxHeader('',$langs->trans("PrintingSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup'); + +//$head=printippadmin_prepare_head(); + + +if ($mode == 'config' && $user->admin) +{ + print '
'; + print ''; + print ''; + + dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); + + print $langs->trans("PrintingDesc")."

\n"; + + print ''; + + $var=true; + print ''; + print ''; + print ''; + print "\n"; + + + $var=!$var; + print ''; + + $var=!$var; + print ''; + + $var=!$var; + print ''; + + $var=!$var; + print ''; + + print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; + print $langs->trans("PRINTIPP_HOST").''; + print ''; + print '   '.$langs->trans("Example").': localhost'; + print '
'; + print $langs->trans("PRINTIPP_PORT").''; + print ''; + print '   '.$langs->trans("Example").': 631'; + print '
'; + print $langs->trans("PRINTIPP_USER").''; + print ''; + print '
'; + print $langs->trans("PRINTIPP_PASSWORD").''; + print ''; + print '
'; + + dol_fiche_end(); + + //print '
'; + + + print ''; + + + //if (count($list) == 0) print $langs->trans("NoPrinterFound"); + + dol_fiche_end(); +} + + + +llxFooter(); + +$db->close(); diff --git a/htdocs/printing/index.php b/htdocs/printing/index.php new file mode 100644 index 00000000000..e8669f44585 --- /dev/null +++ b/htdocs/printing/index.php @@ -0,0 +1,38 @@ + + * + * 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 . + */ + +/** + * \file htdocs/printing/index.php + * \ingroup printing + * \brief Printing + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; + +llxHeader("",$langs->trans("Printing")); + +print_fiche_titre($langs->trans("Printing")); + +// List Jobs from printing modules +//$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); +//$printer->list_jobs('commande'); + +llxFooter(); + +$db->close(); From be60c13de6392290a480ef48509934cebfdc9fd3 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Mon, 8 Dec 2014 20:33:26 +0100 Subject: [PATCH 02/61] WIP Printing System --- .tx/config | 12 + htdocs/core/actions_printing.inc.php | 48 +-- htdocs/core/class/html.formfile.class.php | 10 +- htdocs/core/modules/modPrintIPP.class.php | 156 --------- htdocs/core/modules/modPrinting.class.php | 5 +- .../modules/printing}/index.html | 0 .../modules/printing/modules_printing.php | 86 +++++ .../modules/printing/printgcp.modules.php | 331 ++++++++++++++++++ .../modules/printing/printipp.modules.php | 282 +++++++++++++++ ...nterface_60_modPrinting_Printing.class.php | 71 ---- htdocs/expedition/card.php | 2 + .../install/mysql/migration/3.7.0-3.8.0.sql | 15 + .../{llx_printer_ipp.sql => llx_printing.sql} | 13 +- htdocs/langs/en_US/printgcp.lang | 18 + htdocs/langs/en_US/printing.lang | 10 + htdocs/langs/en_US/printipp.lang | 5 +- htdocs/printing/admin/printing.php | 190 +++++++--- htdocs/{printipp => printing}/lib/index.html | 0 .../lib/printing.lib.php} | 29 +- htdocs/printipp/admin/printipp.php | 246 ------------- htdocs/printipp/index.php | 36 -- 21 files changed, 965 insertions(+), 600 deletions(-) delete mode 100644 htdocs/core/modules/modPrintIPP.class.php rename htdocs/{printipp/admin => core/modules/printing}/index.html (100%) create mode 100644 htdocs/core/modules/printing/modules_printing.php create mode 100644 htdocs/core/modules/printing/printgcp.modules.php create mode 100644 htdocs/core/modules/printing/printipp.modules.php delete mode 100644 htdocs/core/triggers/interface_60_modPrinting_Printing.class.php rename htdocs/install/mysql/tables/{llx_printer_ipp.sql => llx_printing.sql} (83%) create mode 100644 htdocs/langs/en_US/printgcp.lang create mode 100644 htdocs/langs/en_US/printing.lang rename htdocs/{printipp => printing}/lib/index.html (100%) rename htdocs/{printipp/lib/printipp.lib.php => printing/lib/printing.lib.php} (59%) delete mode 100644 htdocs/printipp/admin/printipp.php delete mode 100644 htdocs/printipp/index.php diff --git a/.tx/config b/.tx/config index e4d1fc65732..74875508f29 100644 --- a/.tx/config +++ b/.tx/config @@ -236,6 +236,18 @@ source_file = htdocs/langs/en_US/paypal.lang source_lang = en_US type = MOZILLAPROPERTIES +[dolibarr.printgcp] +file_filter = htdocs/langs//printgcp.lang +source_file = htdocs/langs/en_US/printgcp.lang +source_lang = en_US +type = MOZILLAPROPERTIES + +[dolibarr.printing] +file_filter = htdocs/langs//printing.lang +source_file = htdocs/langs/en_US/printing.lang +source_lang = en_US +type = MOZILLAPROPERTIES + [dolibarr.printipp] file_filter = htdocs/langs//printipp.lang source_file = htdocs/langs/en_US/printipp.lang diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php index f864524fce1..431ac89a94e 100644 --- a/htdocs/core/actions_printing.inc.php +++ b/htdocs/core/actions_printing.inc.php @@ -31,28 +31,34 @@ if ($action == 'print_file' and $user->rights->printing->read) { $langs->load("printing"); - //require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - //$printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - //$result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - // Call trigger to Print Doc - //$actiontypecode='AC_PRINT'; - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $trigger_name='PRINT_DOCPDF'; - $printing->file = GETPOST('file', 'alpha'); - $printing->printer = GETPOST('printer', 'alpha'); - //print print_r($printing, true); + require_once DOL_DOCUMENT_ROOT . '/core/modules/printing/modules_printing.php'; + $objectprint = new PrintingDriver($db); + $list = $objectprint->listDrivers($db, 10); + if (! empty($list)) { + $errorprint=0; + $printed=0; + foreach ($list as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $langs->load($driver); + $classname = 'printing_'.$driver; + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; - $result=$interface->run_triggers($trigger_name,$printing,$user,$langs,$conf); - if ($result < 0) { - setEventMessage($interface->errors, 'errors'); - } - if ($result == 0) { - setEventMessage($langs->trans("NoModuleFound")); - } - - if ($result>0) { - setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file')))); + if (! empty($conf->global->{$printer->active})) { + $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':''); + $errorprint = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir); + //if ($errorprint < 0) { + // setEventMessage($interface->errors, 'errors'); + //} + if ($errorprint=='') { + setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name); + $printed++; + } + } + } + if ($printed==0) setEventMessage($langs->trans("NoActivePrintingModuleFound")); + } else { + setEventMessage($langs->trans("NoModuleFound"), 'warning'); } $action = ''; } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index d2183c582cd..9160213667b 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -272,7 +272,7 @@ class FormFile } $printer=0; - if (in_array($modulepart,array('facture','propal','proposal','order','commande'))) // This feature is implemented only for such elements + if (in_array($modulepart,array('facture','propal','proposal','order','commande','expedition'))) // This feature is implemented only for such elements { $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false; } @@ -603,8 +603,8 @@ class FormFile $out.= ''; if ($delallowed) { - $out.= 'trans("Delete"), 'delete.png').''; @@ -613,8 +613,8 @@ class FormFile if ($printer) { //$out.= ''; - $out.= ' trans("Print"),'printer.png').''; } if ($morepicto) diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrintIPP.class.php deleted file mode 100644 index 1f3d0a71a7a..00000000000 --- a/htdocs/core/modules/modPrintIPP.class.php +++ /dev/null @@ -1,156 +0,0 @@ - - * Copyright (C) 2014 Frederic France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - */ - -/** \defgroup printipp Module printipp - * \brief Module pour imprimer via CUPS - */ - -/** - * \file htdocs/core/modules/modPrintIPP.class.php - * \ingroup printipp - * \brief Fichier de description et activation du module PrintIPP - */ -include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; - - - -/** - * \class modPrintIPP - * \brief Classe de description et activation du module PrintIPP - */ -class modPrintIPP extends DolibarrModules -{ - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db ; - $this->numero = 54000; - // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' - // It is used to group modules in module setup page - $this->family = "other"; - // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) - $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Print via Cups IPP Printer."; - $this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version - $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); - // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) - $this->special = 1; - // Name of image file used for this module. - // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' - // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' - $this->picto = 'technic'; - - // Data directories to create when module is enabled. - $this->dirs = array(); - - // Config pages - $this->config_page_url = array("printipp.php@printipp"); - - // Dependances - $this->hidden = (! empty($_SERVER["WINDIR"])); - $this->depends = array('printing'); - $this->requiredby = array(); - $this->phpmin = array(5,1); // Minimum version of PHP required by module - $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module - $this->conflictwith = array(); - $this->langfiles = array("printipp"); - - // Constantes - $this->const = array(); - - // Boxes - $this->boxes = array(); - - // Permissions - $this->rights = array(); - $this->rights_class = 'printipp'; - - $r=0; - // $this->rights[$r][0] Id permission (unique tous modules confondus) - // $this->rights[$r][1] Libelle par defaut si traduction de cle "PermissionXXX" non trouvee (XXX = Id permission) - // $this->rights[$r][2] Non utilise - // $this->rights[$r][3] 1=Permis par defaut, 0=Non permis par defaut - // $this->rights[$r][4] Niveau 1 pour nommer permission dans code - // $this->rights[$r][5] Niveau 2 pour nommer permission dans code - - $r++; - $this->rights[$r][0] = 54001; - $this->rights[$r][1] = 'Printer'; - $this->rights[$r][2] = 'r'; - $this->rights[$r][3] = 1; - $this->rights[$r][4] = 'read'; - - // Main menu entries - $this->menus = array(); // List of menus to add - $r=0; - - // This is to declare the Top Menu entry: - $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Put 0 if this is a top menu - 'type'=>'left', // This is a Top menu entry - 'titre'=>'Printer', - 'mainmenu'=>'printer', - 'url'=>'/printipp/index.php', - 'langs'=>'printipp', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>300, - 'enabled'=>'$conf->printipp->enabled && $leftmenu==\'modulesadmintools\'', - 'perms'=>'$user->rights->printipp->read', // Use 'perms'=>'1' if you want your menu with no permission rules - 'target'=>'', - 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both - - $r++; - - - } - - /** - * Function called when module is enabled. - * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. - * It also creates data directories - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ - function init($options='') - { - $sql = array(); - - return $this->_init($sql, $options); - } - - /** - * Function called when module is disabled. - * Remove from database constants, boxes and permissions from Dolibarr database. - * Data directories are not deleted - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ - function remove($options='') - { - $sql = array(); - - return $this->_remove($sql, $options); - } - -} diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index 144b023bdc8..00c59eaf285 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -67,7 +67,6 @@ class modPrinting extends DolibarrModules $this->config_page_url = array("printing.php@printing"); // Dependances - $this->hidden = (! empty($_SERVER["WINDIR"])); $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(5,1); // Minimum version of PHP required by module @@ -132,6 +131,7 @@ class modPrinting extends DolibarrModules */ function init($options='') { + // insertion modele dans llx_document_model $sql = array(); return $this->_init($sql, $options); @@ -142,11 +142,12 @@ class modPrinting extends DolibarrModules * Remove from database constants, boxes and permissions from Dolibarr database. * Data directories are not deleted * - * @param string $options Options when enabling module ('', 'noboxes') + * @param string $options Options when enabling module ('', 'noboxes') * @return int 1 if OK, 0 if KO */ function remove($options='') { + // suppression des modeles "printing" $sql = array(); return $this->_remove($sql, $options); diff --git a/htdocs/printipp/admin/index.html b/htdocs/core/modules/printing/index.html similarity index 100% rename from htdocs/printipp/admin/index.html rename to htdocs/core/modules/printing/index.html diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php new file mode 100644 index 00000000000..3b53711f58c --- /dev/null +++ b/htdocs/core/modules/printing/modules_printing.php @@ -0,0 +1,86 @@ + + * + * 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/mailings/modules_printing.php + * \ingroup printing + * \brief File with parent class of printing modules + */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + +/** + * Parent class of emailing target selectors modules + */ +class PrintingDriver +{ + var $db; + var $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Return list of printing driver + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of drivers + */ + static function listDrivers($db,$maxfilenamelength=0) + { + global $conf; + + $type='printing'; + $liste=array(); + + $moduledir=DOL_DOCUMENT_ROOT."/core/modules/printing/"; + $tmpfiles=dol_dir_list($moduledir,'all',0,'\modules.php','','name',SORT_ASC,0); + foreach($tmpfiles as $record) { + $list[$record['fullname']]=str_replace('.modules.php', '',$record['name']); + } + + return $list; + } + + /** + * Return description of Printing Module + * + * @return string Return translation of key PrintingModuleDescXXX where XXX is module name, or $this->desc if not exists + */ + function getDesc() + { + global $langs; + $langs->load("printing"); + $transstring="PrintingModuleDesc".$this->name; + if ($langs->trans($transstring) != $transstring) return $langs->trans($transstring); + else return $this->desc; + } + +} + diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php new file mode 100644 index 00000000000..7041e112811 --- /dev/null +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -0,0 +1,331 @@ +. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printgcp.modules.php + * \ingroup printing + * \brief File to provide printing with Google Cloud Print + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with Google Cloud Print + */ +class printing_printgcp extends PrintingDriver +{ + var $name = 'printgcp'; + var $desc = 'PrintGCPDesc'; + var $picto = 'printer'; + var $active = 'PRINTING_PRINTGCP'; + var $conf = array(); + var $login = ''; + var $password = ''; + var $authtoken = ''; + var $db; + + const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin'; + const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/interface/search'; + const PRINT_URL = 'https://www.google.com/cloudprint/interface/submit'; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db = $db; + $this->login = $conf->global->PRINTGCP_LOGIN; + $this->password = $conf->global->PRINTGCP_PASSWORD; + $this->authtoken = $conf->global->PRINTGCP_AUTHTOKEN; + $this->conf[] = array('varname'=>'PRINTGCP_LOGIN', 'required'=>1, 'example'=>'user@gmail.com', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTGCP_PASSWORD', 'required'=>1, 'example'=>'', 'type'=>'password'); + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $langs->load('printgcp'); + $var=true; + $html = ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''."\n"; + $list = $this->getlist_available_printers(); + //$html.= ''; + $var = true; + foreach ($list['available'] as $printer_det) + { + $var=!$var; + $html.= ""; + $html.= ''; + $html.= ''; + $html.= ''; // id to identify printer to use + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + // Defaut + $html.= ''; + $html.= ''."\n"; + } + + return $html; + } + + /** + * Return list of available printers + * + * @return array list of printers + */ + function getlist_available_printers() + { + global $conf,$db; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + $ret['available'] = $this->get_printer_detail(); + return $ret; + } + + /** + * List of printers + * + * @return array list of printers + */ + public function get_printer_detail() + { + // Check if we have auth token + if(empty($this->authtoken)) { + // We don't have auth token so throw exception + throw new Exception("Please first login to Google by calling loginToGoogle function"); + } + // Prepare auth headers with auth token + $authheaders = array("Authorization: GoogleLogin auth=".$this->authtoken, + "GData-Version: 3.0", + ); + // Make Http call to get printers added by user to Google Cloud Print + $responsedata = $this->makeCurl(self::PRINTERS_SEARCH_URL,array(),$authheaders); + $printers = json_decode($responsedata); + // Check if we have printers? + if(is_null($printers)) { + // We dont have printers so return blank array + return array(); + } else { + // We have printers so returns printers as array + return $this->parsePrinters($printers); + } + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * + * @return string '' if OK, Error message if KO + */ + public function print_file($file, $module, $subdir='') + { + global $conf; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + // si $module=commande_fournisseur alors $conf->fournisseur->commande->dir_output + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + + $this->sendPrintToPrinter($conf->global->PRINTING_GCP_DEFAULT, $file, $fileprint, 'application/pdf'); + } + + /** + * Sends document to the printer + * + * @param string $printerid Printer id returned by Google Cloud Print + * @param string $printjobtitle Job Title + * @param string $filepath File Path to be send to Google Cloud Print + * @param string $contenttype File content type by example application/pdf, image/png + * @return array status array + */ + public function sendPrintToPrinter($printerid,$printjobtitle,$filepath,$contenttype) + { + $errors=0; + // Check auth token + if(empty($this->authtoken)) { + $errors++; + setEventMessage('Please first login to Google', 'warning'); + } + // Check if printer id + if(empty($printerid)) { + $errors++; + setEventMessage('No provided printer ID', 'warning'); + } + // Open the file which needs to be print + $handle = fopen($filepath, "rb"); + if(!$handle) { + $errors++; + setEventMessage('Could not read the file.'); + } + // Read file content + $contents = fread($handle, filesize($filepath)); + fclose($handle); + // Prepare post fields for sending print + $post_fields = array('printerid' => $printerid, + 'title' => $printjobtitle, + 'contentTransferEncoding' => 'base64', + 'content' => base64_encode($contents), // encode file content as base64 + 'contentType' => $contenttype + ); + // Prepare authorization headers + $authheaders = array("Authorization: GoogleLogin auth=" . $this->authtoken); + // Make http call for sending print Job + $response = json_decode($this->makeCurl(self::PRINT_URL,$post_fields,$authheaders)); + // Has document been successfully sent? + if($response->success=="1") { + return array('status' =>true,'errorcode' =>'','errormessage'=>""); + } else { + return array('status' =>false,'errorcode' =>$response->errorCode,'errormessage'=>$response->message); + } + } + + + /** + * Login into Google Account + * + * @return string true or false + */ + function GoogleLogin() + { + global $db, $conf; + // Prepare post fields required for the login + $loginpostfields = array("accountType" => "HOSTED_OR_GOOGLE", + "Email" => $this->login, + "Passwd" => $this->password, + "service" => "cloudprint", + "source" => "GCP" + ); + // Get the Auth token + $loginresponse = $this->makeCurl(self::LOGIN_URL,$loginpostfields); + $token = $this->getAuthToken($loginresponse); + if(! empty($token)&&!is_null($token)) { + $this->authtoken = $token; + $result=dolibarr_set_const($db, 'PRINTGCP_AUTHTOKEN', $token, 'chaine', 0, '', $conf->entity); + return true; + } else { + return false; + } + + } + + /** + * + * Parse json response and return printers array + * @param string $jsonobj Json response object + * @return array return array of printers + */ + private function parsePrinters($jsonobj) + { + $printers = array(); + if (isset($jsonobj->printers)) { + foreach ($jsonobj->printers as $gcpprinter) { + $printers[] = array('id' =>$gcpprinter->id, + 'name' =>$gcpprinter->name, + 'defaultDisplayName' =>$gcpprinter->defaultDisplayName, + 'displayName' =>$gcpprinter->displayName, + 'ownerId' =>$gcpprinter->ownerId, + 'ownerName' =>$gcpprinter->ownerName, + 'connectionStatus' =>$gcpprinter->connectionStatus, + 'status' =>$gcpprinter->status, + 'type' =>$gcpprinter->type + ); + } + } + return $printers; + } + + /** + * Parse data to get auth token + * + * @param string $response response from curl + * @return string token + */ + private function getAuthToken($response) + { + // Search Auth tag + preg_match("/Auth=([a-z0-9_-]+)/i", $response, $matches); + $authtoken = @$matches[1]; + return $authtoken; + } + + /** + * Curl request + * + * @param string $url url to hit + * @param array $postfields array of post fields + * @param array $headers array of http headers + * @return + */ + private function makeCurl($url,$postfields=array(),$headers=array()) + { + // Curl Init + $curl = curl_init($url); + // Curl post request + if(! empty($postfields)) { + // As is HTTP post curl request so set post fields + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); + } + // Curl request headers + if(! empty($headers)) { + // As curl requires header so set headers here + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + } + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + // Execute the curl and return response + $response = curl_exec($curl); + curl_close($curl); + return $response; + } + + +} diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php new file mode 100644 index 00000000000..5252341c2d3 --- /dev/null +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -0,0 +1,282 @@ +. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printipp.modules.php + * \ingroup mailing + * \brief File to provide printing with PrintIPP + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with PrintIPP + */ +class printing_printipp extends PrintingDriver +{ + var $name='printipp'; + var $desc='PrintIPPDesc'; + var $picto='printer'; + var $active='PRINTING_PRINTIPP'; + var $conf=array(); + var $host; + var $port; + var $userid; /* user login */ + var $user; + var $password; + var $error; + var $db; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db=$db; + $this->host=$conf->global->PRINTIPP_HOST; + $this->port=$conf->global->PRINTIPP_PORT; + $this->user=$conf->global->PRINTIPP_USER; + $this->password=$conf->global->PRINTIPP_PASSWORD; + $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password'); + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * @param string $subdir subdirectory of document like for expedition subdir is sendings + * + * @return string '' if OK, Error message if KO + */ + function print_file($file, $module, $subdir='') + { + global $conf,$db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setJobName($file,true); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + + // select printer uri for module order, propal,... + $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp"'; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $ipp->setPrinterURI($obj->printer_id); + } + else + { + if (! empty($conf->global->PRINTIPP_URI_DEFAULT)) + { + $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT); + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } + + // Set number of copy + $ipp->setCopies($obj->copy); + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + $ipp->setData($fileprint); + $ipp->printJob(); + + return ''; + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $var=true; + $html = '
NamedisplayNameIdOwnerNameStateconnectionStatusType'.$langs->trans("Select").'
'.print_r($list,true).'
'.$printer_det['name'].''.$printer_det['displayName'].''.$printer_det['id'].''.$printer_det['ownerName'].''.$printer_det['status'].''.$langs->trans('STATE_'.$printer_det['connectionStatus']).''.$langs->trans('TYPE_'.$printer_det['type']).''; + if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id']) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= ''.img_picto($langs->trans("Disabled"),'off').''; + $html.= '
'; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= "\n"; + $list = $this->getlist_available_printers(); + $var = true; + foreach ($list as $value) + { + $var=!$var; + $printer_det = $this->get_printer_detail($value); + $html.= ""; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; + // Defaut + $html.= ''; + $html.= ''."\n"; + } + + return $html; + } + + /** + * Return list of available printers + * + * @return array list of printers + */ + function getlist_available_printers() + { + global $conf,$db; + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->getPrinters(); + return $ipp->available_printers; + } + + /** + * Get printer detail + * + * @param string $uri URI + * @return array List of attributes + */ + function get_printer_detail($uri) + { + global $conf,$db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->setPrinterURI($uri); + $ipp->getPrinterAttributes(); + return $ipp->printer_attributes; + } + + /** + * List jobs print + * + * @param string $module module + * + * @return void + */ + function list_jobs($module) + { + global $conf, $db, $bc; + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + // select printer uri for module order, propal,... + $sql = 'SELECT rowid,printer_uri,printer_name FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"'; + $result = $this->db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $ipp->setPrinterURI($obj->printer_uri); + } + else + { + // All printers + $ipp->setPrinterURI("ipp://localhost:631/printers/"); + } + } + // Getting Jobs + $ipp->getJobs(false,0,'completed',false); + print '
UriNameStateState_reasonState_reason1BWColorDeviceMediaSupported'.$langs->trans("Select").'
'.$value.'
'.print_r($printer_det,true).'
'.$printer_det->printer_name->_value0.''.$printer_det->printer_state->_value0.''.$printer_det->printer_state_reasons->_value0.''.$printer_det->printer_state_reasons->_value1.''.$printer_det->printer_type->_value2.''.$printer_det->printer_type->_value3.''.$printer_det->device_uri->_value0.''.$printer_det->media_default->_value0.''.$printer_det->media_type_supported->_value1.''; + if ($conf->global->PRINTIPP_URI_DEFAULT == $value) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= ''.img_picto($langs->trans("Disabled"),'off').''; + $html.= '
'; + print ''; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print "\n"; + $jobs = $ipp->jobs_attributes; + $var = True; + //print '
'.print_r($jobs,true).'
'; + foreach ($jobs as $value ) + { + $var=!$var; + print ""; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + print "
IdOwnerPrinterFileStatusCancel
'.$value->job_id->_value0.''.$value->job_originating_user_name->_value0.''.$value->printer_uri->_value0.''.$value->job_name->_value0.''.$value->job_state->_value0.''.$value->job_uri->_value0.'
"; + } + +} diff --git a/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php b/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php deleted file mode 100644 index b02b16f4796..00000000000 --- a/htdocs/core/triggers/interface_60_modPrinting_Printing.class.php +++ /dev/null @@ -1,71 +0,0 @@ - - * Copyright (C) 2005-2014 Regis Houssin - * Copyright (C) 2014 Marcos García - * - * 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 . - */ - -/** - * \file htdocs/core/triggers/interface_60_modPrinting_Printing.class.php - * \ingroup printing - * \brief Trigger call by printing to print with PrintIPP - * \remarks - */ -require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; - - -/** - * Class of triggers for printing - */ -class InterfacePrinting extends DolibarrTriggers -{ - - public $family = 'printing'; - public $picto = 'technic'; - public $description = "Triggers of this module is used for printing via PrintIPP."; - public $version = self::VERSION_DOLIBARR; - - /** - * Function called when a Dolibarrr business event is done. - * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared) - * - * @param string $action Event action code - * @param Object $object Object - * @param User $user Object user - * @param Translate $langs Object langs - * @param conf $conf Object conf - * @return int <0 if KO, 0 if no triggered ran, >0 if OK - */ - public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - global $db; - // Put here code you want to execute when a Dolibarr business events occurs. - // Data and type of action are stored into $object and $action - - // Actions - - if ($action=='PRINT_DOCPDF') { - require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - $result = $printer->print_file($object->file, $object->printer); - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - //$this->errors[]='test'; - //return -1; - return 1; - } - return 0; - } - -} diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index b4ca3504347..1f01d4ad981 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -414,6 +414,8 @@ if (GETPOST('removedfile','alpha')) $action ='presend'; } +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + /* * Send mail */ diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index a190f102023..ee73492d9f0 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -26,4 +26,19 @@ create table llx_c_price_expression expression varchar(80) NOT NULL )ENGINE=innodb; +--create table for user conf of printing driver +CREATE TABLE llx_printing +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + datec datetime, + printer_name text NOT NULL, + printer_location text NOT NULL, + printer_id varchar(255) NOT NULL, + copy integer NOT NULL DEFAULT '1', + module varchar(16) NOT NULL, + driver varchar(16) NOT NULL, + userid integer +)ENGINE=innodb; + ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_printer_ipp.sql b/htdocs/install/mysql/tables/llx_printing.sql similarity index 83% rename from htdocs/install/mysql/tables/llx_printer_ipp.sql rename to htdocs/install/mysql/tables/llx_printing.sql index a19e05587d6..3da96b1e6b8 100644 --- a/htdocs/install/mysql/tables/llx_printer_ipp.sql +++ b/htdocs/install/mysql/tables/llx_printing.sql @@ -1,5 +1,5 @@ -- ============================================================================ --- Copyright (C) 2013 Florian HENRY +-- Copyright (C) 2014 Frederic France -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -16,15 +16,16 @@ -- -- ============================================================================ -CREATE TABLE llx_printer_ipp +CREATE TABLE llx_printing ( rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - datec datetime, + tms timestamp, + datec datetime, printer_name text NOT NULL, printer_location text NOT NULL, - printer_uri varchar(255) NOT NULL, + printer_id varchar(255) NOT NULL, copy integer NOT NULL DEFAULT '1', module varchar(16) NOT NULL, - login varchar(32) NOT NULL + driver varchar(16) NOT NULL, + userid integer )ENGINE=innodb; diff --git a/htdocs/langs/en_US/printgcp.lang b/htdocs/langs/en_US/printgcp.lang new file mode 100644 index 00000000000..9751649a738 --- /dev/null +++ b/htdocs/langs/en_US/printgcp.lang @@ -0,0 +1,18 @@ +# Dolibarr language file - Source file is en_US - printgccp +PRINTGCP=Google Cloud Print +PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print. +PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print. +PrintTestDescprintgcp=List of Printers for Google Cloud Print. +PRINTGCP_LOGIN=Google Account Login +PRINTGCP_PASSWORD=Google Account Password +STATE_ONLINE=Online +STATE_UNKNOWN=Unknown +STATE_OFFLINE=Offline +STATE_DORMANT=Offline for quite a while +TYPE_GOOGLE=Google +TYPE_HP=HP Printer +TYPE_DOCS=DOCS +TYPE_DRIVE=Google Drive +TYPE_FEDEX=Fedex +TYPE_ANDROID_CHROME_SNAPSHOT=Android +TYPE_IOS_CHROME_SNAPSHOT=IOS diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang new file mode 100644 index 00000000000..77c63884636 --- /dev/null +++ b/htdocs/langs/en_US/printing.lang @@ -0,0 +1,10 @@ +# Dolibarr language file - Source file is en_US - printing +PrintingSetup=Setup of Printing System +PrintingDesc=This module adds a Print button to send documents directly to a printer with various module. +ModuleDriverSetup=Setup Module Driver +PrintingDriverDesc=Configuration variables for printing driver. +ListDrivers=List of drivers +PrintTestDesc=List of Printers. +FileWasSentToPrinter=File %s was sent to printer +NoActivePrintingModuleFound=No active module to print document +PleaseSelectaDriverfromList=Please select a driver from list. diff --git a/htdocs/langs/en_US/printipp.lang b/htdocs/langs/en_US/printipp.lang index 835e6827f12..2a10ddfe710 100644 --- a/htdocs/langs/en_US/printipp.lang +++ b/htdocs/langs/en_US/printipp.lang @@ -1,6 +1,9 @@ # Dolibarr language file - Source file is en_US - printipp +PRINTIPP=PrintIPP Driver PrintIPPSetup=Setup of Direct Print module -PrintIPPDesc=This module adds a Print button to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintIPPDesc=This driver allow to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintingDriverDescprintipp=Configuration variables for printing driver PrintIPP. +PrintTestDescprintipp=List of Printers for driver PrintIPP. PRINTIPP_ENABLED=Show "Direct print" icon in document lists PRINTIPP_HOST=Print server PRINTIPP_PORT=Port diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index 29bd8787fa0..f12c235dc2c 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -26,8 +26,8 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; -//require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; -//require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; +require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php'; $langs->load("admin"); $langs->load("printing"); @@ -37,14 +37,58 @@ if (! $user->admin) accessforbidden(); $action = GETPOST('action','alpha'); $mode = GETPOST('mode','alpha'); $value = GETPOST('value','alpha'); +$varname = GETPOST('varname', 'alpha'); +$driver = GETPOST('driver', 'alpha'); + +if (! empty($driver)) $langs->load($driver); if (!$mode) $mode='config'; /* * Action */ +if ($action == 'setconst' && $user->admin) +{ + $error=0; + $db->begin(); + foreach ($_POST['setupdriver'] as $setupconst) { + //print '
'.print_r($setupconst, true).'
'; + $result=dolibarr_set_const($db, $setupconst['varname'],$setupconst['value'],'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + } + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action=''; +} +if ($action == 'setvalue' && $user->admin) +{ + $db->begin(); + + $result=dolibarr_set_const($db, $varname, $value,'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action = ''; +} /* * View @@ -55,73 +99,131 @@ $form = new Form($db); llxHeader('',$langs->trans("PrintingSetup")); $linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup'); +print_fiche_titre($langs->trans("PrintingSetup"),$linkback,'setup'); -//$head=printippadmin_prepare_head(); +$head=printingadmin_prepare_head(); +if ($mode == 'setup' && $user->admin) +{ + print '
'; + print ''; + print ''; + dol_fiche_head($head, $mode, $langs->trans("ModuleDriverSetup"), 0, 'technic'); + + print $langs->trans("PrintingDriverDesc".$driver)."

\n"; + + print ''."\n"; + $var=true; + print ''; + print ''; + print ''; + print "\n"; + + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + $i=0; + foreach ($printer->conf as $key) { + $var=!$var; + print ''; + print ''.$langs->trans($key['varname']).''; + $i++; + } + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + + print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; + print ''; + print ''; + print ' '.($key['example']!=''?$langs->trans("Example").' : '.$key['example']:''); + print '
'; + if (! empty($driver)) { + print '
'; + } + print ''; + dol_fiche_end(); + +} if ($mode == 'config' && $user->admin) { - print '
'; - print ''; - print ''; - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); print $langs->trans("PrintingDesc")."

\n"; - print ''; + print '
'."\n"; $var=true; print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print "\n"; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; + $object = new PrintingDriver($db); + $result = $object->listDrivers($db, 10); + foreach ($result as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + } print '
'.$langs->trans("Parameters").''.$langs->trans("Value").''.$langs->trans("Description").''.$langs->trans("Active").''.$langs->trans("Setup").''.$langs->trans("Test").'
'; - print $langs->trans("PRINTIPP_HOST").''; - print ''; - print '   '.$langs->trans("Example").': localhost'; - print '
'; - print $langs->trans("PRINTIPP_PORT").''; - print ''; - print '   '.$langs->trans("Example").': 631'; - print '
'; - print $langs->trans("PRINTIPP_USER").''; - print ''; - print '
'; - print $langs->trans("PRINTIPP_PASSWORD").''; - print ''; - print '
'.img_picto('', $printer->picto).$langs->trans($printer->desc).''; + if (! empty($conf->use_javascript_ajax)) + { + print ajax_constantonoff($printer->active); + } + else + { + if (empty($conf->global->{$printer->conf})) + { + print ''.img_picto($langs->trans("Disabled"),'off').''; + } + else + { + print ''.img_picto($langs->trans("Enabled"),'on').''; + } + } + print ''.img_picto('', 'setup').''.img_picto('', 'setup').'
'; dol_fiche_end(); +} + +if ($mode == 'test' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("PrintingTest"), 0, 'technic'); + + print $langs->trans('PrintTestDesc'.$driver)."

\n"; - //print '
'; - + print ''; + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $printer = new $classname($db); + //print '
'.print_r($printer, true).'
'; + print $printer->listAvailablePrinters(); - print ''; - - - //if (count($list) == 0) print $langs->trans("NoPrinterFound"); + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + print '
'; dol_fiche_end(); } - llxFooter(); $db->close(); diff --git a/htdocs/printipp/lib/index.html b/htdocs/printing/lib/index.html similarity index 100% rename from htdocs/printipp/lib/index.html rename to htdocs/printing/lib/index.html diff --git a/htdocs/printipp/lib/printipp.lib.php b/htdocs/printing/lib/printing.lib.php similarity index 59% rename from htdocs/printipp/lib/printipp.lib.php rename to htdocs/printing/lib/printing.lib.php index 64c14609df5..fd02c240b15 100644 --- a/htdocs/printipp/lib/printipp.lib.php +++ b/htdocs/printing/lib/printing.lib.php @@ -16,44 +16,49 @@ */ /** - * \file htdocs/printipp/lib/printipp.lib.php - * \ingroup printipp - * \brief Library for printipp functions + * \file htdocs/printing/lib/printing.lib.php + * \ingroup printing + * \brief Library for printing functions */ /** - * Define head array for tabs of printipp tools setup pages + * Define head array for tabs of printing tools setup pages * * @return Array of head */ -function printippadmin_prepare_head() +function printingadmin_prepare_head() { global $langs, $conf; $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=config"; - $head[$h][1] = $langs->trans("CupsServer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=config"; + $head[$h][1] = $langs->trans("ListDrivers"); $head[$h][2] = 'config'; $h++; - $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=test"; - $head[$h][1] = $langs->trans("Printer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup"; + $head[$h][1] = $langs->trans("SetupDriver"); + $head[$h][2] = 'setup'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test"; + $head[$h][1] = $langs->trans("TestDriver"); $head[$h][2] = 'test'; $h++; - $object=new stdClass(); + //$object=new stdClass(); // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab // $this->tabs = array('entity:-tabname); to remove a tab - complete_head_from_modules($conf,$langs,$object,$head,$h,'printippadmin'); + //complete_head_from_modules($conf,$langs,$object,$head,$h,'printingadmin'); - complete_head_from_modules($conf,$langs,$object,$head,$h,'printipp','remove'); + //complete_head_from_modules($conf,$langs,$object,$head,$h,'printing','remove'); return $head; } diff --git a/htdocs/printipp/admin/printipp.php b/htdocs/printipp/admin/printipp.php deleted file mode 100644 index 28ad55453eb..00000000000 --- a/htdocs/printipp/admin/printipp.php +++ /dev/null @@ -1,246 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/printipp/admin/printipp.php - * \ingroup printipp - * \brief Page to setup printipp module - */ - -require '../../main.inc.php'; - -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; -require_once DOL_DOCUMENT_ROOT.'/printipp/lib/printipp.lib.php'; - -$langs->load("admin"); -$langs->load("printipp"); - -if (! $user->admin) accessforbidden(); - -$action = GETPOST('action','alpha'); -$mode = GETPOST('mode','alpha'); -$value = GETPOST('value','alpha'); - -if (!$mode) $mode='config'; - -/* - * Action - */ - -if ($action == 'setvalue' && $user->admin) -{ - $db->begin(); - - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_HOST",GETPOST('PRINTIPP_HOST','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_PORT",GETPOST('PRINTIPP_PORT','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_USER",GETPOST('PRINTIPP_USER','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - $result=dolibarr_set_const($db, "PRINTIPP_PASSWORD",GETPOST('PRINTIPP_PASSWORD','alpha'),'chaine',0,'',$conf->entity); - if (! $result > 0) $error++; - - if (! $error) - { - $db->commit(); - setEventMessage($langs->trans("SetupSaved")); - } - else - { - $db->rollback(); - dol_print_error($db); - } -} - -// Set default model -else if ($action == 'setprinteruri') -{ - if (dolibarr_set_const($db, "PRINTIPP_URI_DEFAULT",$value,'chaine',0,'',$conf->entity)) - { - // La constante qui a ete lue en avant du nouveau set - // on passe donc par une variable pour avoir un affichage coherent - $conf->global->PRINTIPP_URI_DEFAULT = $value; - } -} - - -/* - * View - */ - -$form = new Form($db); - -llxHeader('',$langs->trans("PrintIPPSetup")); - -$linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup'); - -$head=printippadmin_prepare_head(); - - -if ($mode == 'config' && $user->admin) -{ - print '
'; - print ''; - print ''; - - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."

\n"; - - print ''; - - $var=true; - print ''; - print ''; - print ''; - print "\n"; - - /* - $var=!$var; - print ''; - */ - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - //$var=true; - //print ''; - //print ''; - //print ''; - //print "\n"; - - print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; - print $langs->trans("PRINTIPP_ENABLED").''; - - if (! empty($conf->use_javascript_ajax)) - { - print ajax_constantonoff('PRINTIPP_ENABLED'); - } - else - { - if (empty($conf->global->PRINTIPP_ENABLED)) - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - else - { - print ''.img_picto($langs->trans("Enabled"),'on').''; - } - } - print '
'; - print $langs->trans("PRINTIPP_HOST").''; - print ''; - print '   '.$langs->trans("Example").': localhost'; - print '
'; - print $langs->trans("PRINTIPP_PORT").''; - print ''; - print '   '.$langs->trans("Example").': 631'; - print '
'; - print $langs->trans("PRINTIPP_USER").''; - print ''; - print '
'; - print $langs->trans("PRINTIPP_PASSWORD").''; - print ''; - print '
'.$langs->trans("OtherParameter").''.$langs->trans("Value").'
'; - - dol_fiche_end(); - - print '
'; - - print ''; -} - -if ($mode == 'test' && $user->admin) -{ - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."

\n"; - - print ''; - $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); - $var=true; - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print "\n"; - - $list = $printer->getlist_available_printers(); - $var = true; - foreach ($list as $value) - { - $var=!$var; - $printer_det = $printer->get_printer_detail($value); - print ""; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - // Defaut - print "'; - print "\n"; - } - print '
UriNameStateState_reasonState_reason1BWColorDeviceMediaSupported'.$langs->trans("Select").'
'.$value.'
'.print_r($printer_det,true).'
'.$printer_det->printer_name->_value0.''.$printer_det->printer_state->_value0.''.$printer_det->printer_state_reasons->_value0.''.$printer_det->printer_state_reasons->_value1.''.$printer_det->printer_type->_value2.''.$printer_det->printer_type->_value3.''.$printer_det->device_uri->_value0.''.$printer_det->media_default->_value0.''.$printer_det->media_type_supported->_value1.'"; - if ($conf->global->PRINTIPP_URI_DEFAULT == "$value") - { - print img_picto($langs->trans("Default"),'on'); - } - else - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - print '
'; - - if (count($list) == 0) print $langs->trans("NoPrinterFound"); - - dol_fiche_end(); -} - - - -llxFooter(); - -$db->close(); diff --git a/htdocs/printipp/index.php b/htdocs/printipp/index.php deleted file mode 100644 index a130805f16e..00000000000 --- a/htdocs/printipp/index.php +++ /dev/null @@ -1,36 +0,0 @@ -. - */ - -/** - * \file htdocs/printipp/index.php - * \ingroup printipp - * \brief Printipp - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; - -llxHeader("",$langs->trans("Printer")); - -print_fiche_titre($langs->trans("Printer")); - -$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); -$printer->list_jobs('commande'); - -llxFooter(); - -$db->close(); From 9bb1999dc2f1191c438d94c5866c450a9edc4f7c Mon Sep 17 00:00:00 2001 From: frederic34 Date: Mon, 8 Dec 2014 21:07:24 +0100 Subject: [PATCH 03/61] Some correct --- .../core/modules/printing/printgcp.modules.php | 16 ++++++++-------- htdocs/install/mysql/tables/llx_printing.sql | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index 7041e112811..b9cc1aa0b37 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -130,7 +130,7 @@ class printing_printgcp extends PrintingDriver * * @return array list of printers */ - public function get_printer_detail() + function get_printer_detail() { // Check if we have auth token if(empty($this->authtoken)) { @@ -159,10 +159,10 @@ class printing_printgcp extends PrintingDriver * * @param string $file file * @param string $module module - * + * @param string $subdir subdir for file * @return string '' if OK, Error message if KO */ - public function print_file($file, $module, $subdir='') + function print_file($file, $module, $subdir='') { global $conf; if ($this->authtoken=='') { @@ -256,8 +256,8 @@ class printing_printgcp extends PrintingDriver } /** - * * Parse json response and return printers array + * * @param string $jsonobj Json response object * @return array return array of printers */ @@ -298,10 +298,10 @@ class printing_printgcp extends PrintingDriver /** * Curl request * - * @param string $url url to hit - * @param array $postfields array of post fields - * @param array $headers array of http headers - * @return + * @param string $url url to hit + * @param array $postfields array of post fields + * @param array $headers array of http headers + * @return array response from curl */ private function makeCurl($url,$postfields=array(),$headers=array()) { diff --git a/htdocs/install/mysql/tables/llx_printing.sql b/htdocs/install/mysql/tables/llx_printing.sql index 3da96b1e6b8..451564ff74b 100644 --- a/htdocs/install/mysql/tables/llx_printing.sql +++ b/htdocs/install/mysql/tables/llx_printing.sql @@ -1,5 +1,6 @@ -- ============================================================================ --- Copyright (C) 2014 Frederic France +-- Copyright (C) 2013 Florian HENRY +-- Copyright (C) 2014 Frederic France -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by From 715d0f18db80f617b455c593318de3ef8905b433 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Mon, 8 Dec 2014 21:52:53 +0100 Subject: [PATCH 04/61] Lang correction --- htdocs/core/modules/modPrinting.class.php | 2 -- .../modules/printing/printgcp.modules.php | 14 ++++---- .../modules/printing/printipp.modules.php | 32 +++++++++---------- htdocs/langs/en_US/printgcp.lang | 7 ++++ htdocs/langs/en_US/printipp.lang | 20 ++++++++++++ 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index 00c59eaf285..12d73e33875 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -131,7 +131,6 @@ class modPrinting extends DolibarrModules */ function init($options='') { - // insertion modele dans llx_document_model $sql = array(); return $this->_init($sql, $options); @@ -147,7 +146,6 @@ class modPrinting extends DolibarrModules */ function remove($options='') { - // suppression des modeles "printing" $sql = array(); return $this->_remove($sql, $options); diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index b9cc1aa0b37..de414b9d18b 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -72,13 +72,13 @@ class printing_printgcp extends PrintingDriver $var=true; $html = ''; $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; $html.= ''; $html.= ''."\n"; $list = $this->getlist_available_printers(); diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index 5252341c2d3..7f789b859eb 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -131,16 +131,16 @@ class printing_printipp extends PrintingDriver $var=true; $html = '
NamedisplayNameIdOwnerNameStateconnectionStatusType'.$langs->trans('GCP_Name').''.$langs->trans('GCP_displayName').''.$langs->trans('GCP_Id').''.$langs->trans('GCP_OwnerName').''.$langs->trans('GCP_State').''.$langs->trans('GCP_connectionStatus').''.$langs->trans('GCP_Type').''.$langs->trans("Select").'
'; $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - //$html.= ''; - $html.= ''; - $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + //$html.= ''; + $html.= ''; + $html.= ''; $html.= ''; $html.= "\n"; $list = $this->getlist_available_printers(); @@ -153,14 +153,14 @@ class printing_printipp extends PrintingDriver $html.= ''; //$html.= ''; $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; - $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; //$html.= ''; $html.= ''; - $html.= ''; + $html.= ''; // Defaut $html.= ''; print ''; print ''; + print ''; print "\n"; - $sql = 'SELECT p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; + $sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; $resql = $db->query($sql); while ($row=$db->fetch_array($resql)) { $var=!$var; @@ -254,6 +263,7 @@ if ($mode == 'userconf' && $user->admin) print ''; print ''; print ''; + print ''; print "\n"; } print '
UriNameStateState_reasonState_reason1BWColorDeviceMediaSupported'.$langs->trans('IPP_Uri').''.$langs->trans('IPP_Name').''.$langs->trans('IPP_State').''.$langs->trans('IPP_State_reason').''.$langs->trans('IPP_State_reason1').''.$langs->trans('IPP_BW').''.$langs->trans('IPP_Color').''.$langs->trans('IPP_Device').''.$langs->trans('IPP_Media').''.$langs->trans('IPP_Supported').''.$langs->trans("Select").'
'.$value.'
'.print_r($printer_det,true).'
'.$printer_det->printer_name->_value0.''.$printer_det->printer_state->_value0.''.$printer_det->printer_state_reasons->_value0.''.$printer_det->printer_state_reasons->_value1.''.$printer_det->printer_type->_value2.''.$printer_det->printer_type->_value3.''.$langs->trans('STATE_IPP_'.$printer_det->printer_state->_value0).''.$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value0).''.(! empty($printer_det->printer_state_reasons->_value1)?$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value1):'').''.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value2).''.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value3).''.$printer_det->device_uri->_value0.''.$printer_det->media_default->_value0.''.$printer_det->media_type_supported->_value1.''.$langs->trans('MEDIA_IPP_'.$printer_det->media_type_supported->_value1).''; if ($conf->global->PRINTIPP_URI_DEFAULT == $value) diff --git a/htdocs/langs/en_US/printgcp.lang b/htdocs/langs/en_US/printgcp.lang index 9751649a738..ded5fb63d6e 100644 --- a/htdocs/langs/en_US/printgcp.lang +++ b/htdocs/langs/en_US/printgcp.lang @@ -16,3 +16,10 @@ TYPE_DRIVE=Google Drive TYPE_FEDEX=Fedex TYPE_ANDROID_CHROME_SNAPSHOT=Android TYPE_IOS_CHROME_SNAPSHOT=IOS +GCP_Name=Name +GCP_displayName=Display Name +GCP_Id=Printer Id +GCP_OwnerName=Owner Name +GCP_State=Printer State +GCP_connectionStatus=Online State +GCP_Type=Printer Type diff --git a/htdocs/langs/en_US/printipp.lang b/htdocs/langs/en_US/printipp.lang index 2a10ddfe710..e85d53627c4 100644 --- a/htdocs/langs/en_US/printipp.lang +++ b/htdocs/langs/en_US/printipp.lang @@ -15,3 +15,23 @@ NoDefaultPrinterDefined=No default printer defined DefaultPrinter=Default printer Printer=Printer CupsServer=CUPS Server +IPP_Uri=Printer Uri +IPP_Name=Printer Name +IPP_State=Printer State +IPP_State_reason=State reason +IPP_State_reason1=State reason1 +IPP_BW=BW +IPP_Color=Color +IPP_Device=Device +IPP_Media=Printer media +IPP_Supported=Type of media +STATE_IPP_idle=Idle +STATE_IPP_stopped=Stopped +STATE_IPP_paused=Paused +STATE_IPP_toner-low-report=Low Toner +STATE_IPP_none=None +MEDIA_IPP_stationery=Stationery +MEDIA_IPP_thermal=Thermal +IPP_COLOR_print-black=BW Printer +IPP_COLOR_print-color=Color Printer +IPP_COLOR_=No From 16d860b3f7156fd87779c50144c37a973e9560b6 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Mon, 8 Dec 2014 22:17:28 +0100 Subject: [PATCH 05/61] Lang Correction --- htdocs/core/class/html.formfile.class.php | 6 +++--- htdocs/core/modules/printing/printgcp.modules.php | 2 ++ htdocs/core/modules/printing/printipp.modules.php | 2 ++ htdocs/langs/en_US/main.lang | 1 + htdocs/printing/admin/printing.php | 2 ++ 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 5081af493d5..c67a3196b33 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -614,9 +614,9 @@ class FormFile if ($printer) { //$out.= ''; - $out.= ' '.img_picto($langs->trans("Print"),'printer.png').''; + $out.= ' '.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').''; } if ($morepicto) { diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index de414b9d18b..ab0ed428a69 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -1,5 +1,7 @@ + * * 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 diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index 7f789b859eb..013d9922e10 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -1,5 +1,7 @@ + * * 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 diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index cbc4deb40d7..4b27d7b285d 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -683,6 +683,7 @@ XMoreLines=%s line(s) hidden PublicUrl=Public URL AddBox=Add box SelectElementAndClickRefresh=Select an element and click Refresh +PrintFile=Print File %s # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index f12c235dc2c..9db8a55af82 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -123,6 +123,7 @@ if ($mode == 'setup' && $user->admin) if (! empty($driver)) { require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; $classname = 'printing_'.$driver; + $langs->load($driver); $printer = new $classname($db); //print '
'.print_r($printer, true).'
'; $i=0; @@ -211,6 +212,7 @@ if ($mode == 'test' && $user->admin) if (! empty($driver)) { require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; $classname = 'printing_'.$driver; + $langs->load($driver); $printer = new $classname($db); //print '
'.print_r($printer, true).'
'; print $printer->listAvailablePrinters(); From 6b4d7b973b475a0501dd4b8052f2808d7a3cbb17 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Mon, 8 Dec 2014 23:30:17 +0100 Subject: [PATCH 06/61] Some changes --- htdocs/core/modules/modPrinting.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index 12d73e33875..f578c463d43 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -51,7 +51,7 @@ class modPrinting extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Enable Printing System."; - $this->version = 'experimental'; // 'development' or 'experimental' or 'dolibarr' or version + $this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) $this->special = 1; From 608f4a7d7d8624d296c5530bd1f35e9cc6927f18 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Tue, 9 Dec 2014 23:37:04 +0100 Subject: [PATCH 07/61] Some correct html --- htdocs/core/modules/printing/printgcp.modules.php | 4 ++-- htdocs/core/modules/printing/printipp.modules.php | 4 ++-- htdocs/printing/admin/printing.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index ab0ed428a69..be479dd82f7 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -72,8 +72,8 @@ class printing_printgcp extends PrintingDriver global $bc, $conf, $langs; $langs->load('printgcp'); $var=true; - $html = ''; - $html.= ''; + + $html = ''; $html.= ''; $html.= ''; $html.= ''; diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index 013d9922e10..2e4b4c7161a 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -131,8 +131,8 @@ class printing_printipp extends PrintingDriver { global $bc, $conf, $langs; $var=true; - $html = '
'.$langs->trans('GCP_Name').''.$langs->trans('GCP_displayName').''.$langs->trans('GCP_Id').'
'; - $html.= ''; + + $html = ''; $html.= ''; $html.= ''; $html.= ''; diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index 9db8a55af82..53b192c35e4 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -208,7 +208,7 @@ if ($mode == 'test' && $user->admin) print $langs->trans('PrintTestDesc'.$driver)."

\n"; - print '
'.$langs->trans('IPP_Uri').''.$langs->trans('IPP_Name').''.$langs->trans('IPP_State').'
'; + print '
'; if (! empty($driver)) { require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; $classname = 'printing_'.$driver; From df28ce77c084455b94a6864d8097058eaf9b221c Mon Sep 17 00:00:00 2001 From: frederic34 Date: Thu, 11 Dec 2014 21:58:56 +0100 Subject: [PATCH 08/61] Some progress on Printing --- .../modules/printing/printgcp.modules.php | 26 ++++++++++++-- .../modules/printing/printipp.modules.php | 4 +-- htdocs/printing/admin/printing.php | 36 +++++++++++++++++++ htdocs/printing/lib/printing.lib.php | 5 +++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index be479dd82f7..2091c1a89eb 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -166,7 +166,7 @@ class printing_printgcp extends PrintingDriver */ function print_file($file, $module, $subdir='') { - global $conf; + global $conf, $user, $db; if ($this->authtoken=='') { $this->GoogleLogin(); } @@ -174,8 +174,30 @@ class printing_printgcp extends PrintingDriver $fileprint=$conf->{$module}->dir_output; if ($subdir!='') $fileprint.='/'.$subdir; $fileprint.='/'.$file; + // select printer uri for module order, propal,... + $sql = 'SELECT rowid, printer_id, copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printgcp" AND userid='.$user->id; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $printer_id=$obj->printer_id; + } + else + { + if (! empty($conf->global->PRINTIPP_GCP_DEFAULT)) + { + $printer_id=$conf->global->PRINTIPP_GCP_DEFAULT; + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } - $this->sendPrintToPrinter($conf->global->PRINTING_GCP_DEFAULT, $file, $fileprint, 'application/pdf'); + $this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf'); } /** diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index 2e4b4c7161a..c8a19bffa31 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -76,7 +76,7 @@ class printing_printipp extends PrintingDriver */ function print_file($file, $module, $subdir='') { - global $conf,$db; + global $conf, $user, $db; include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; @@ -89,7 +89,7 @@ class printing_printipp extends PrintingDriver if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); // select printer uri for module order, propal,... - $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp"'; + $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp" AND userid='.$user->id; $result = $db->query($sql); if ($result) { diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index 53b192c35e4..64823e63195 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -225,6 +225,42 @@ if ($mode == 'test' && $user->admin) dol_fiche_end(); } +if ($mode == 'userconf' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("UserConf"), 0, 'technic'); + + print $langs->trans('PrintUserConfDesc'.$driver)."

\n"; + + print '
'; + $var=true; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + $sql = 'SELECT p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; + $resql = $db->query($sql); + while ($row=$db->fetch_array($resql)) { + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + print '
'.$langs->trans("User").''.$langs->trans("PrintModule").''.$langs->trans("PrintDriver").''.$langs->trans("Printer").''.$langs->trans("PrinterLocation").''.$langs->trans("PrinterId").''.$langs->trans("NumberOfCopy").'
'.$row['login'].''.$row['module'].''.$row['driver'].''.$row['printer_name'].''.$row['printer_location'].''.$row['printer_id'].''.$row['copy'].'
'; + + dol_fiche_end(); + +} llxFooter(); diff --git a/htdocs/printing/lib/printing.lib.php b/htdocs/printing/lib/printing.lib.php index fd02c240b15..1d09daba0dc 100644 --- a/htdocs/printing/lib/printing.lib.php +++ b/htdocs/printing/lib/printing.lib.php @@ -50,6 +50,11 @@ function printingadmin_prepare_head() $head[$h][2] = 'test'; $h++; + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf"; + $head[$h][1] = $langs->trans("UserConf"); + $head[$h][2] = 'userconf'; + $h++; + //$object=new stdClass(); // Show more tabs from modules From 74f8f83432c0c099ac5cce2e241eb407f054c952 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sat, 13 Dec 2014 13:53:48 +0100 Subject: [PATCH 09/61] WIP Printing --- htdocs/printing/admin/printing.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index 64823e63195..63784e560f0 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -47,6 +47,14 @@ if (!$mode) $mode='config'; /* * Action */ + +if (($mode == 'test' || $mode == 'setup') && empty($driver)) +{ + setEventMessage($langs->trans('PleaseSelectaDriverfromList')); + header("Location: ".$_SERVER['PHP_SELF'].'?mode=config'); + exit; +} + if ($action == 'setconst' && $user->admin) { $error=0; @@ -241,8 +249,9 @@ if ($mode == 'userconf' && $user->admin) print '
'.$langs->trans("PrinterLocation").''.$langs->trans("PrinterId").''.$langs->trans("NumberOfCopy").''.$langs->trans("Delete").'
'.$row['printer_location'].''.$row['printer_id'].''.$row['copy'].''.img_picto($langs->trans("Delete"), 'delete').'
'; From da7dc2a393cb4722ad320f6a8c6726a5e433f09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 25 Dec 2014 22:02:22 +0100 Subject: [PATCH 10/61] Fix: [ bug #1765 ] Unable to create a contract --- htdocs/contrat/class/contrat.class.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index ae384195162..6dd9c5661b3 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -46,7 +46,6 @@ class Contrat extends CommonObject var $id; var $ref; - var $ref_ext; var $ref_supplier; var $socid; var $societe; // Objet societe @@ -413,7 +412,6 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi,"; $sql.= " note_private, note_public, model_pdf, extraparams"; $sql.= " ,ref_supplier"; - $sql.= " ,ref_ext"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat"; if ($ref) { @@ -433,7 +431,6 @@ class Contrat extends CommonObject $this->id = $result["rowid"]; $this->ref = (!isset($result["ref"]) || !$result["ref"]) ? $result["rowid"] : $result["ref"]; $this->ref_supplier = $result["ref_supplier"]; - $this->ref_ext = $result["ref_ext"]; $this->statut = $result["statut"]; $this->mise_en_service = $this->db->jdate($result["datemise"]); $this->date_contrat = $this->db->jdate($result["datecontrat"]); @@ -735,7 +732,7 @@ class Contrat extends CommonObject // Insert contract $sql = "INSERT INTO ".MAIN_DB_PREFIX."contrat (datec, fk_soc, fk_user_author, date_contrat,"; $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; - $sql.= " ref, entity, note_private, note_public, ref_supplier, ref_ext)"; + $sql.= " ref, entity, note_private, note_public, ref_supplier)"; $sql.= " VALUES ('".$this->db->idate($now)."',".$this->socid.",".$user->id; $sql.= ", '".$this->db->idate($this->date_contrat)."'"; $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); @@ -746,7 +743,6 @@ class Contrat extends CommonObject $sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); $sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql.= ", ".(!empty($this->ref_supplier)?("'".$this->db->escape($this->ref_supplier)."'"):"NULL"); - $sql.= ", ".(!empty($this->ref_ext)?("'".$this->db->escape($this->ref_ext)."'"):"NULL"); $sql.= ")"; $resql=$this->db->query($sql); if ($resql) @@ -998,7 +994,6 @@ class Contrat extends CommonObject if (isset($this->ref)) $this->ref=trim($this->ref); if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier); - if (isset($this->ref_ext)) $this->ref_ext=trim($this->ref_ext); if (isset($this->entity)) $this->entity=trim($this->entity); if (isset($this->statut)) $this->statut=trim($this->statut); if (isset($this->fk_soc)) $this->fk_soc=trim($this->fk_soc); @@ -1022,7 +1017,6 @@ class Contrat extends CommonObject $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; $sql.= " ref_supplier=".(isset($this->ref_supplier)?"'".$this->db->escape($this->ref_supplier)."'":"null").","; - $sql.= " ref_ext=".(isset($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null").","; $sql.= " entity=".$conf->entity.","; $sql.= " date_contrat=".(dol_strlen($this->date_contrat)!=0 ? "'".$this->db->idate($this->date_contrat)."'" : 'null').","; $sql.= " statut=".(isset($this->statut)?$this->statut:"null").","; From 310be3d3b690cae935ae0d1004e47a934923a09a Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sun, 28 Dec 2014 11:29:53 +0100 Subject: [PATCH 11/61] Update lib with github.com/mfly/php-ipp --- htdocs/includes/printipp/BasicIPP.php | 3846 ++++++++--------- htdocs/includes/printipp/CupsPrintIPP.php | 631 +-- htdocs/includes/printipp/ExtendedPrintIPP.php | 1139 +++-- htdocs/includes/printipp/PrintIPP.php | 1617 +++---- htdocs/includes/printipp/http_class.php | 1035 +++-- 5 files changed, 4365 insertions(+), 3903 deletions(-) diff --git a/htdocs/includes/printipp/BasicIPP.php b/htdocs/includes/printipp/BasicIPP.php index 3869c75bc06..1cc7851fab2 100644 --- a/htdocs/includes/printipp/BasicIPP.php +++ b/htdocs/includes/printipp/BasicIPP.php @@ -1,6 +1,6 @@ errno = $errno; - } - public function getErrorFormatted() - { - $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), - $this->getMessage() , $this->getFile() , $this->getLine()); - return $return; - } - public function getErrno() - { - return $this->errno; - } + protected $errno; + + public function __construct($msg, $errno = null) + { + parent::__construct($msg); + $this->errno = $errno; + } + + public function getErrorFormatted() + { + $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), + $this->getMessage() , $this->getFile() , $this->getLine()); + return $return; + } + + public function getErrno() + { + return $this->errno; + } } class BasicIPP { - // - // variables declaration - // - - // setup variables - - public $paths = array( - "root" => "/", - "admin" => "/admin/", - "printers" => "/printers/", - "jobs" => "/jobs/" - ); - public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30. - public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30. - public $ssl = false; - public $debug_level = 3; // max 3: almost silent - public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and reads while end tag) - public $with_exceptions = 0; // compatibility mode for old scripts - public $handle_http_exceptions = 1; - - // readables variables - - public $jobs = array(); - public $jobs_uri = array(); - public $status = array(); - public $response_completed = array(); - public $last_job = ""; - public $attributes; // object you can read: attributes after validateJob() - public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes() - public $job_attributes; // object you can read: last job attributes - public $jobs_attributes; // object you can read: jobs attributes after getJobs() - public $available_printers = array(); - public $printers_uri = array(); - public $debug = array(); - public $response; - - // protected variables; - protected $log_level = 2; // max 3: very verbose - protected $log_type = 3; // 3: file | 1: e-mail | 0: logger - protected $log_destination; // e-mail or file - protected $serveroutput; - protected $setup; - protected $stringjob; - protected $data; - protected $debug_count = 0; - protected $username; - protected $charset; - protected $password; - protected $requesring_user; - protected $client_hostname = "localhost"; - protected $stream; - protected $host = "localhost"; - protected $port = "631"; - protected $printer_uri; - protected $timeout = "20"; //20 secs - protected $errNo; - protected $errStr; - protected $datatype; - protected $datahead; - protected $datatail; - public $meta; - protected $operation_id; - protected $delay; - protected $error_generation; //devel feature - protected $debug_http = 0; - protected $no_disconnect; - protected $job_tags; - protected $operation_tags; - protected $index; - protected $collection; //RFC3382 - protected $collection_index; //RFC3382 - protected $collection_key = array(); //RFC3382 - protected $collection_depth = - 1; //RFC3382 - protected $end_collection = false; //RFC3382 - protected $collection_nbr = array(); //RFC3382 - protected $unix = false; // true -> use unix sockets instead of http - - // constructor - public function __construct() - { - $tz = getenv("date.timezone"); - if (!$tz) $tz = @date_default_timezone_get(); - date_default_timezone_set($tz); - $this->meta = new stdClass(); - $this->setup = new stdClass(); - $this->values = new stdClass(); - $this->serveroutput = new stdClass(); - $this->error_generation = new stdClass(); - $this->_parsing = new stdClass(); - self::_initTags(); - } - - /***************** - * - * PUBLIC FUNCTIONS - * - *******************/ - - // - // SETUP - // - - public function setPort($port = '631') - { - $this->port = $port; - self::_putDebug("Port is " . $this->port, 2); - } - - public function setUnix($socket = '/var/run/cups/cups.sock') - { - $this->host = $socket; - $this->unix = true; - self::_putDebug("Host is " . $this->host, 2); - } - - public function setHost($host = 'localhost') - { - $this->host = $host; - $this->unix = false; - self::_putDebug("Host is " . $this->host, 2); - } - - public function setTimeout($timeout) - { - $this->timeout = $timeout; - } - - public function setPrinterURI($uri) - { - $length = strlen($uri); - $length = chr($length); - while (strlen($length) < 2) $length = chr(0x00) . $length; - $this->meta->printer_uri = chr(0x45) // uri type | value-tag - . chr(0x00) . chr(0x0B) // name-length - . "printer-uri" // printer-uri | name - . $length . $uri; - $this->printer_uri = $uri; - self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2); - $this->setup->uri = 1; - } - - public function setData($data) - { - $this->data = $data; - self::_putDebug("Data set", 2); - } - - public function setRawText() - { - $this->setup->datatype = 'TEXT'; - $this->meta->mime_media_type = ""; - $this->setup->mime_media_type = 1; - $this->datahead = chr(0x16); - if (is_readable($this->data)) - { - //It's a filename. Open and stream. - $data = fopen($this->data, "rb"); - while (!feof($data)) $output = fread($data, 8192); - } - else - { - $output = $this->data; - } - if (substr($output, -1, 1) != chr(0x0c)) if (!isset($this->setup->noFormFeed)) $this->datatail = chr(0x0c); - self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2); - } - - public function unsetRawText() - { - $this->setup->datatype = 'BINARY'; - $this->datahead = ''; - $this->datatail = ''; - self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2); - } - - public function setBinary() - { - self::unsetRawText(); - } - - public function setFormFeed() - { - $this->datatail = "\r\n" . chr(0x0c); - unset($this->setup->noFormFeed); - } - - public function unsetFormFeed() - { - $this->datatail = ''; - $this->setup->noFormFeed = 1; - } - - public function setCharset($charset = 'us-ascii') - { - $charset = strtolower($charset); - $this->charset = $charset; - $this->meta->charset = chr(0x47) // charset type | value-tag - . chr(0x00) . chr(0x12) // name-length - . "attributes-charset" // attributes-charset | name - . self::_giveMeStringLength($charset) // value-length - . $charset; // value - self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2); - $this->setup->charset = 1; - } - - public function setLanguage($language = 'en_us') - { - $language = strtolower($language); - $this->meta->language = chr(0x48) // natural-language type | value-tag - . chr(0x00) . chr(0x1B) // name-length - . "attributes-natural-language" //attributes-natural-language - . self::_giveMeStringLength($language) // value-length - . $language; // value - self::_putDebug(sprintf(_("Language: %s") , $language) , 2); - $this->setup->language = 1; - } - - public function setDocumentFormat($mime_media_type = 'application/octet-stream') - { - self::setBinary(); - $length = chr(strlen($mime_media_type)); - while (strlen($length) < 2) $length = chr(0x00) . $length; - self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2); - $this->meta->mime_media_type = chr(0x49) // document-format tag - . self::_giveMeStringLength('document-format') . 'document-format' // - . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value - $this->setup->mime_media_type = 1; - } - - // setDocumentFormat alias for backward compatibility - public function setMimeMediaType($mime_media_type = "application/octet-stream") - { - self::setDocumentFormat($mime_media_type); - } - - public function setCopies($nbrcopies = 1) - { - $this->meta->copies = ""; - if ($nbrcopies == 1 || !$nbrcopies) return true; - $copies = self::_integerBuild($nbrcopies); - $this->meta->copies = chr(0x21) // integer type | value-tag - . chr(0x00) . chr(0x06) // name-length - . "copies" // copies | name - . self::_giveMeStringLength($copies) // value-length - . $copies; - self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2); - $this->setup->copies = 1; - } - - public function setDocumentName($document_name = "") - { - $this->meta->document_name = ""; - if (!$document_name) return true; - $document_name = substr($document_name, 0, 1023); - $length = strlen($document_name); - $length = chr($length); - while (strlen($length) < 2) $length = chr(0x00) . $length; - self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2); - $this->meta->document_name = chr(0x41) // textWithoutLanguage tag - . chr(0x00) . chr(0x0d) // name-length - . "document-name" // mimeMediaType - . self::_giveMeStringLength($document_name) . $document_name; // value - - } - - public function setJobName($jobname = '', $absolute = false) - { - $this->meta->jobname = ''; - if ($jobname == '') - { - $this->meta->jobname = ''; - return true; - } - $postpend = date('-H:i:s-') . $this->_setJobId(); - if ($absolute) $postpend = ''; - if (isset($this->values->jobname) && $jobname == '(PHP)') - { - $jobname = $this->values->jobname; - } - $this->values->jobname = $jobname; - $jobname.= $postpend; - $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag - . chr(0x00) . chr(0x08) // name-length - . "job-name" // job-name || name - . self::_giveMeStringLength($jobname) // value-length - . $jobname; // value - self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2); - $this->setup->jobname = 1; - } - - public function setUserName($username = 'PHP-SERVER') - { - $this->requesting_user = $username; - $this->meta->username = ''; - if (!$username) return true; - if ($username == 'PHP-SERVER' && isset($this->meta->username)) return TRUE; - /* - $value_length = 0x00; - for ($i = 0; $i < strlen($username); $i++) - { - $value_length+= 0x01; - } - $value_length = chr($value_length); - while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length; - */ - $this->meta->username = chr(0x42) // keyword type || value-tag - . chr(0x00) . chr(0x14) // name-length - . "requesting-user-name" - . self::_giveMeStringLength($username) // value-length - . $username; - self::_putDebug(sprintf(_("Username: %s") , $username) , 2); - $this->setup->username = 1; - } - - public function setAuthentification($username, $password) - { - self::setAuthentication($username, $password); - } - - public function setAuthentication($username, $password) - { - $this->password = $password; - $this->username = $username; - self::_putDebug(_("Setting password") , 2); - $this->setup->password = 1; - } - - public function setSides($sides = 2) - { - $this->meta->sides = ''; - if (!$sides) return true; - switch ($sides) - { - case 1: - $sides = "one-sided"; - break; - - case 2: - $sides = "two-sided-long-edge"; - break; - - case "2CE": - $sides = "two-sided-short-edge"; - break; - - default: - $sides = $sides; // yeah, what ? - break; - } - $this->meta->sides = chr(0x44) // keyword type | value-tag - . chr(0x00) . chr(0x05) // name-length - . "sides" // sides | name - . self::_giveMeStringLength($sides) // value-length - . $sides; // one-sided | value - self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2); - } - - public function setFidelity() - { - // whether the server can't replace any attributes - // (eg, 2 sided print is not possible, - // so print one sided) and DO NOT THE JOB. - $this->meta->fidelity = chr(0x22) // boolean type | value-tag - . chr(0x00) . chr(0x16) // name-length - . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name - . chr(0x00) . chr(0x01) // value-length - . chr(0x01); // true | value - self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3); - } - - public function unsetFidelity() - { - // whether the server can replace any attributes - // (eg, 2 sided print is not possible, - // so print one sided) and DO THE JOB. - $this->meta->fidelity = chr(0x22) // boolean type | value-tag - . chr(0x00) . chr(0x16) // name-length - . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name - . chr(0x00) . chr(0x01) // value-length - . chr(0x00); // false | value - self::_putDebug(_("Fidelity attribute is unset") , 2); - } - - public function setMessage($message = '') - { - $this->meta->message = ''; - if (!$message) return true; - $this->meta->message = - chr(0x41) // attribute type = textWithoutLanguage - . chr(0x00) - . chr(0x07) - . "message" - . self::_giveMeStringLength(substr($message, 0, 127)) - . substr($message, 0, 127); - self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2); - } - - public function setPageRanges($page_ranges) - { - // $pages_ranges = string: "1:5 10:25 40:52 ..." - // to unset, specify an empty string. - $this->meta->page_range = ''; - if (!$page_ranges) return true; - $page_ranges = trim(str_replace("-", ":", $page_ranges)); - $first = true; - #$page_ranges = split(' ', $page_ranges); - $page_ranges = preg_split('# #', $page_ranges); - foreach($page_ranges as $page_range) - { - $value = self::_rangeOfIntegerBuild($page_range); - if ($first) - { - $this->meta->page_ranges .= - $this->tags_types['rangeOfInteger']['tag'] - . self::_giveMeStringLength('page-ranges') - . 'page-ranges' - . self::_giveMeStringLength($value) - . $value; - } - else - { - $this->meta->page_ranges .= - $this->tags_types['rangeOfInteger']['tag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($value) - . $value; - $first = false; - } - } - } - - public function setAttribute($attribute, $values) - { - $operation_attributes_tags = array_keys($this->operation_tags); - $job_attributes_tags = array_keys($this->job_tags); - $printer_attributes_tags = array_keys($this->printer_tags); - self::unsetAttribute($attribute); - if (in_array($attribute, $operation_attributes_tags)) - { - if (!is_array($values)) - { - self::_setOperationAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setOperationAttribute($attribute, $value); - } - } - } - elseif (in_array($attribute, $job_attributes_tags)) - { - if (!is_array($values)) - { - self::_setJobAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setJobAttribute($attribute, $value); - } - } - } - elseif (in_array($attribute, $printer_attributes_tags)) - { - if (!is_array($values)) - { - self::_setPrinterAttribute($attribute, $values); - } - else - { - foreach($values as $value) - { - self::_setPrinterAttribute($attribute, $value); - } - } - } - else - { - trigger_error( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , E_USER_NOTICE); - self::_putDebug( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 3); - self::_errorLog( - sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 2); - return FALSE; - } - } - - public function unsetAttribute($attribute) - { - $operation_attributes_tags = array_keys($this->operation_tags); - $job_attributes_tags = array_keys($this->job_tags); - $printer_attributes_tags = array_keys($this->printer_tags); - if (in_array($attribute, $operation_attributes_tags)) - { - unset( - $this->operation_tags[$attribute]['value'], - $this->operation_tags[$attribute]['systag'] - ); - } - elseif (in_array($attribute, $job_attributes_tags)) - { - unset( - $this->job_tags[$attribute]['value'], - $this->job_tags[$attribute]['systag'] - ); - } - elseif (in_array($attribute, $printer_attributes_tags)) - { - unset( - $this->printer_tags[$attribute]['value'], - $this->printer_tags[$attribute]['systag'] - ); - } - else - { - trigger_error( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , E_USER_NOTICE); - self::_putDebug( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 3); - self::_errorLog( - sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), - $attribute) , 2); - return FALSE; - } - return true; - } - - // - // LOGGING / DEBUGGING - // - - public function setLog($log_destination, $destination_type = 'file', $level = 2) - { - - if (is_string($log_destination) && !empty($log_destination)) - { - $this->log_destination = $log_destination; - } - - switch ($destination_type) - { - case 'file': - case 3: - $this->log_destination = $log_destination; - $this->log_type = 3; - break; - - case 'logger': - case 0: - $this->log_destination = ''; - $this->log_type = 0; - break; - - case 'e-mail': - case 1: - $this->log_destination = $log_destination; - $this->log_type = 1; - break; - } - $this->log_level = $level; - } - - public function printDebug() - { - for ($i = 0; $i < $this->debug_count; $i++) - { - echo $this->debug[$i], "\n"; - } - $this->debug = array(); - $this->debug_count = 0; - } - - public function getDebug() - { - $debug = ''; - for ($i = 0; $i < $this->debug_count; $i++) - { - $debug.= $this->debug[$i]; - } - $this->debug = array(); - $this->debug_count = 0; - return $debug; - } - - // - // OPERATIONS - // - - public function printJob() - { - // this BASIC version of printJob do not parse server - // output for job's attributes - self::_putDebug( - sprintf( - "************** Date: %s ***********", - date('Y-m-d H:i:s') - ) - ); - if (!$this->_stringJob()) return FALSE; - if (is_readable($this->data)) - { - self::_putDebug(_("Printing a FILE")); - $this->output = $this->stringjob; - if ($this->setup->datatype == "TEXT") - { - $this->output.= chr(0x16); - } - $post_values = array( - "Content-Type" => "application/ipp", - "Data" => $this->output, - "File" => $this->data - ); - if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) - { - $post_values = array_merge( - $post_values, - array( - "Filetype" => "TEXT" - ) - ); - } - } - else - { - self::_putDebug(_("Printing DATA")); - $this->output = - $this->stringjob - . $this->datahead - . $this->data - . $this->datatail; - $post_values = array( - "Content-Type" => "application/ipp", - "Data" => $this->output - ); - } - if (self::_sendHttp($post_values, $this->paths["printers"])) - { - self::_parseServerOutput(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) - { - $this->status = array_merge($this->status, array( - $this->serveroutput->status - )); - if ($this->serveroutput->status == "successfull-ok") - { - self::_errorLog( - sprintf("printing job %s: ", $this->last_job) - . $this->serveroutput->status, - 3); - } - else - { - self::_errorLog( - sprintf("printing job: ", $this->last_job) - . $this->serveroutput->status, - 1); - } - return $this->serveroutput->status; - } - - $this->status = - array_merge($this->status, array("OPERATION FAILED")); - $this->jobs = - array_merge($this->jobs, array("")); - $this->jobs_uri = - array_merge($this->jobs_uri, array("")); - - self::_errorLog("printing job : OPERATION FAILED", 1); - return false; - } - - - /****************** - * - * PROTECTED FUNCTIONS - * - *******************/ - - // - // HTTP OUTPUT - // - - protected function _sendHttp($post_values, $uri) - { - /* - This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos - */ - $this->response_completed[] = "no"; - unset($this->serverouptut); - self::_putDebug(_("Processing HTTP request") , 2); - $this->serveroutput->headers = array(); - $this->serveroutput->body = ""; - $http = new http_class; - if (!$this->unix) $http->host = $this->host; - else $http->host = "localhost"; - $http->with_exceptions = $this->with_exceptions; - if ($this->debug_http) - { - $http->debug = 1; - $http->html_debug = 0; - } - else - { - $http->debug = 0; - $http->html_debug = 0; - } - $url = "http://" . $this->host; - if ($this->ssl) $url = "https://" . $this->host; - if ($this->unix) $url = "unix://" . $this->host; - $http->port = $this->port; - $http->timeout = $this->http_timeout; - $http->data_timeout = $this->http_data_timeout; - $http->force_multipart_form_post = false; - $http->user = $this->username; - $http->password = $this->password; - $error = $http->GetRequestArguments($url, $arguments); - $arguments["RequestMethod"] = "POST"; - $arguments["Headers"] = array( - "Content-Type" => "application/ipp" + public $paths = array( + "root" => "/", + "admin" => "/admin/", + "printers" => "/printers/", + "jobs" => "/jobs/" ); - $arguments["BodyStream"] = array( - array( - "Data" => $post_values["Data"] - ) - ); - if (isset($post_values["File"])) $arguments["BodyStream"][] = array( - "File" => $post_values["File"] - ); - if (isset($post_values["FileType"]) - && !strcmp($post_values["FileType"], "TEXT")) - { - $arguments["BodyStream"][] = array("Data" => Chr(12)); - } - $arguments["RequestURI"] = $uri; - if ($this->with_exceptions && $this->handle_http_exceptions) - { - try - { - $success = $http->Open($arguments); - } - catch(httpException $e) - { - throw new ippException( - sprintf("http error: %s", $e->getMessage()), - $e->getErrno()); - } - } - else - { - $success = $http->Open($arguments); - } - if ($success[0] == true) - { - $success = $http->SendRequest($arguments); - if ($success[0] == true) - { - self::_putDebug("H T T P R E Q U E S T :"); - self::_putDebug("Request headers:"); - for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) + public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30. + public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30. + public $ssl = false; + public $debug_level = 3; // max 3: almost silent + public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and reads while end tag) + public $with_exceptions = 0; // compatibility mode for old scripts + public $handle_http_exceptions = 1; + + // readables variables + public $jobs = array(); + public $jobs_uri = array(); + public $status = array(); + public $response_completed = array(); + public $last_job = ""; + public $attributes; // object you can read: attributes after validateJob() + public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes() + public $job_attributes; // object you can read: last job attributes + public $jobs_attributes; // object you can read: jobs attributes after getJobs() + public $available_printers = array(); + public $printer_map = array(); + public $printers_uri = array(); + public $debug = array(); + public $response; + public $meta; + + // protected variables; + protected $log_level = 2; // max 3: very verbose + protected $log_type = 3; // 3: file | 1: e-mail | 0: logger + protected $log_destination; // e-mail or file + protected $serveroutput; + protected $setup; + protected $stringjob; + protected $data; + protected $debug_count = 0; + protected $username; + protected $charset; + protected $password; + protected $requesring_user; + protected $client_hostname = "localhost"; + protected $stream; + protected $host = "localhost"; + protected $port = "631"; + protected $requesting_user = ''; + protected $printer_uri; + protected $timeout = "20"; //20 secs + protected $errNo; + protected $errStr; + protected $datatype; + protected $datahead; + protected $datatail; + protected $operation_id; + protected $delay; + protected $error_generation; //devel feature + protected $debug_http = 0; + protected $no_disconnect; + protected $job_tags; + protected $operation_tags; + protected $index; + protected $collection; //RFC3382 + protected $collection_index; //RFC3382 + protected $collection_key = array(); //RFC3382 + protected $collection_depth = - 1; //RFC3382 + protected $end_collection = false; //RFC3382 + protected $collection_nbr = array(); //RFC3382 + protected $unix = false; // true -> use unix sockets instead of http + protected $output; + + public function __construct() { - $header_name = Key($http->request_headers); - if (GetType($http->request_headers[$header_name]) == "array") - { - for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++) - { - self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]); - } - } - else - { - self::_putDebug($header_name . ": " . $http->request_headers[$header_name]); - } + $tz = getenv("date.timezone"); + if (!$tz) + { + $tz = @date_default_timezone_get(); + } + + date_default_timezone_set($tz); + $this->meta = new \stdClass(); + $this->setup = new \stdClass(); + $this->values = new \stdClass(); + $this->serveroutput = new \stdClass(); + $this->error_generation = new \stdClass(); + $this->_parsing = new \stdClass(); + self::_initTags(); } - self::_putDebug("Request body:"); - self::_putDebug( - htmlspecialchars($http->request_body) - . "*********** END REQUEST BODY *********" + + public function setPort($port = '631') + { + $this->port = $port; + self::_putDebug("Port is " . $this->port, 2); + } + + public function setUnix($socket = '/var/run/cups/cups.sock') + { + $this->host = $socket; + $this->unix = true; + self::_putDebug("Host is " . $this->host, 2); + } + + public function setHost($host = 'localhost') + { + $this->host = $host; + $this->unix = false; + self::_putDebug("Host is " . $this->host, 2); + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + public function setPrinterURI($uri) + { + $length = strlen($uri); + $length = chr($length); + while (strlen($length) < 2) $length = chr(0x00) . $length; + $this->meta->printer_uri = chr(0x45) // uri type | value-tag + . chr(0x00) . chr(0x0B) // name-length + . "printer-uri" // printer-uri | name + . $length . $uri; + $this->printer_uri = $uri; + self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2); + $this->setup->uri = 1; + } + + public function setData($data) + { + $this->data = $data; + self::_putDebug("Data set", 2); + } + + public function setRawText() + { + $this->setup->datatype = 'TEXT'; + $this->meta->mime_media_type = ""; + $this->setup->mime_media_type = 1; + $this->datahead = chr(0x16); + if (is_readable($this->data)) + { + //It's a filename. Open and stream. + $data = fopen($this->data, "rb"); + while (!feof($data)) $output = fread($data, 8192); + } + else + { + $output = $this->data; + } + if (substr($output, -1, 1) != chr(0x0c)) { + if (!isset($this->setup->noFormFeed)) + { + $this->datatail = chr(0x0c); + } + } + self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2); + } + + public function unsetRawText() + { + $this->setup->datatype = 'BINARY'; + $this->datahead = ''; + $this->datatail = ''; + self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2); + } + + public function setBinary() + { + self::unsetRawText(); + } + + public function setFormFeed() + { + $this->datatail = "\r\n" . chr(0x0c); + unset($this->setup->noFormFeed); + } + + public function unsetFormFeed() + { + $this->datatail = ''; + $this->setup->noFormFeed = 1; + } + + public function setCharset($charset = 'utf-8') + { + $charset = strtolower($charset); + $this->charset = $charset; + $this->meta->charset = chr(0x47) // charset type | value-tag + . chr(0x00) . chr(0x12) // name-length + . "attributes-charset" // attributes-charset | name + . self::_giveMeStringLength($charset) // value-length + . $charset; // value + self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2); + $this->setup->charset = 1; + } + + public function setLanguage($language = 'en_us') + { + $language = strtolower($language); + $this->meta->language = chr(0x48) // natural-language type | value-tag + . chr(0x00) . chr(0x1B) // name-length + . "attributes-natural-language" //attributes-natural-language + . self::_giveMeStringLength($language) // value-length + . $language; // value + self::_putDebug(sprintf(_("Language: %s") , $language) , 2); + $this->setup->language = 1; + } + + public function setDocumentFormat($mime_media_type = 'application/octet-stream') + { + self::setBinary(); + $length = chr(strlen($mime_media_type)); + while (strlen($length) < 2) $length = chr(0x00) . $length; + self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2); + $this->meta->mime_media_type = chr(0x49) // document-format tag + . self::_giveMeStringLength('document-format') . 'document-format' // + . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value + $this->setup->mime_media_type = 1; + } + + // setDocumentFormat alias for backward compatibility + public function setMimeMediaType($mime_media_type = "application/octet-stream") + { + self::setDocumentFormat($mime_media_type); + } + + public function setCopies($nbrcopies = 1) + { + $this->meta->copies = ""; + + if ($nbrcopies == 1 || !$nbrcopies) + { + return true; + } + + $copies = self::_integerBuild($nbrcopies); + $this->meta->copies = chr(0x21) // integer type | value-tag + . chr(0x00) . chr(0x06) // name-length + . "copies" // copies | name + . self::_giveMeStringLength($copies) // value-length + . $copies; + self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2); + $this->setup->copies = 1; + } + + public function setDocumentName($document_name = "") + { + $this->meta->document_name = ""; + if (!$document_name) { + return true; + } + $document_name = substr($document_name, 0, 1023); + $length = strlen($document_name); + $length = chr($length); + while (strlen($length) < 2) $length = chr(0x00) . $length; + self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2); + $this->meta->document_name = chr(0x41) // textWithoutLanguage tag + . chr(0x00) . chr(0x0d) // name-length + . "document-name" // mimeMediaType + . self::_giveMeStringLength($document_name) . $document_name; // value + + } + + public function setJobName($jobname = '', $absolute = false) + { + $this->meta->jobname = ''; + if ($jobname == '') + { + $this->meta->jobname = ''; + return true; + } + $postpend = date('-H:i:s-') . $this->_setJobId(); + if ($absolute) { + $postpend = ''; + } + if (isset($this->values->jobname) && $jobname == '(PHP)') + { + $jobname = $this->values->jobname; + } + $this->values->jobname = $jobname; + $jobname.= $postpend; + $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag + . chr(0x00) . chr(0x08) // name-length + . "job-name" // job-name || name + . self::_giveMeStringLength($jobname) // value-length + . $jobname; // value + self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2); + $this->setup->jobname = 1; + } + + public function setUserName($username = 'PHP-SERVER') + { + $this->requesting_user = $username; + $this->meta->username = ''; + if (!$username) { + return true; + } + if ($username == 'PHP-SERVER' && isset($this->meta->username)) { + return TRUE; + } + /* + $value_length = 0x00; + for ($i = 0; $i < strlen($username); $i++) + { + $value_length+= 0x01; + } + $value_length = chr($value_length); + while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length; + */ + $this->meta->username = chr(0x42) // keyword type || value-tag + . chr(0x00) . chr(0x14) // name-length + . "requesting-user-name" + . self::_giveMeStringLength($username) // value-length + . $username; + self::_putDebug(sprintf(_("Username: %s") , $username) , 2); + $this->setup->username = 1; + } + + public function setAuthentification($username, $password) + { + self::setAuthentication($username, $password); + } + + public function setAuthentication($username, $password) + { + $this->password = $password; + $this->username = $username; + self::_putDebug(_("Setting password") , 2); + $this->setup->password = 1; + } + + public function setSides($sides = 2) + { + $this->meta->sides = ''; + if (!$sides) + { + return true; + } + + switch ($sides) + { + case 1: + $sides = "one-sided"; + break; + + case 2: + $sides = "two-sided-long-edge"; + break; + + case "2CE": + $sides = "two-sided-short-edge"; + break; + } + + $this->meta->sides = chr(0x44) // keyword type | value-tag + . chr(0x00) . chr(0x05) // name-length + . "sides" // sides | name + . self::_giveMeStringLength($sides) // value-length + . $sides; // one-sided | value + self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2); + } + + public function setFidelity() + { + // whether the server can't replace any attributes + // (eg, 2 sided print is not possible, + // so print one sided) and DO NOT THE JOB. + $this->meta->fidelity = chr(0x22) // boolean type | value-tag + . chr(0x00) . chr(0x16) // name-length + . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name + . chr(0x00) . chr(0x01) // value-length + . chr(0x01); // true | value + self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3); + } + + public function unsetFidelity() + { + // whether the server can replace any attributes + // (eg, 2 sided print is not possible, + // so print one sided) and DO THE JOB. + $this->meta->fidelity = chr(0x22) // boolean type | value-tag + . chr(0x00) . chr(0x16) // name-length + . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name + . chr(0x00) . chr(0x01) // value-length + . chr(0x00); // false | value + self::_putDebug(_("Fidelity attribute is unset") , 2); + } + + public function setMessage($message = '') + { + $this->meta->message = ''; + if (!$message) { + return true; + } + $this->meta->message = + chr(0x41) // attribute type = textWithoutLanguage + . chr(0x00) + . chr(0x07) + . "message" + . self::_giveMeStringLength(substr($message, 0, 127)) + . substr($message, 0, 127); + self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2); + } + + public function setPageRanges($page_ranges) + { + // $pages_ranges = string: "1:5 10:25 40:52 ..." + // to unset, specify an empty string. + $this->meta->page_range = ''; + if (!$page_ranges) { + return true; + } + $page_ranges = trim(str_replace("-", ":", $page_ranges)); + $first = true; + #$page_ranges = split(' ', $page_ranges); + $page_ranges = preg_split('# #', $page_ranges); + foreach($page_ranges as $page_range) + { + $value = self::_rangeOfIntegerBuild($page_range); + if ($first) + { + $this->meta->page_ranges .= + $this->tags_types['rangeOfInteger']['tag'] + . self::_giveMeStringLength('page-ranges') + . 'page-ranges' + . self::_giveMeStringLength($value) + . $value; + } + else + { + $this->meta->page_ranges .= + $this->tags_types['rangeOfInteger']['tag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($value) + . $value; + $first = false; + } + } + } + + public function setAttribute($attribute, $values) + { + $operation_attributes_tags = array_keys($this->operation_tags); + $job_attributes_tags = array_keys($this->job_tags); + $printer_attributes_tags = array_keys($this->printer_tags); + self::unsetAttribute($attribute); + if (in_array($attribute, $operation_attributes_tags)) + { + if (!is_array($values)) + { + self::_setOperationAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setOperationAttribute($attribute, $value); + } + } + } + elseif (in_array($attribute, $job_attributes_tags)) + { + if (!is_array($values)) + { + self::_setJobAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setJobAttribute($attribute, $value); + } + } + } + elseif (in_array($attribute, $printer_attributes_tags)) + { + if (!is_array($values)) + { + self::_setPrinterAttribute($attribute, $values); + } + else + { + foreach($values as $value) + { + self::_setPrinterAttribute($attribute, $value); + } + } + } + else + { + trigger_error( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , E_USER_NOTICE); + self::_putDebug( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 3); + self::_errorLog( + sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 2); + return FALSE; + } + } + + public function unsetAttribute($attribute) + { + $operation_attributes_tags = array_keys($this->operation_tags); + $job_attributes_tags = array_keys($this->job_tags); + $printer_attributes_tags = array_keys($this->printer_tags); + if (in_array($attribute, $operation_attributes_tags)) + { + unset( + $this->operation_tags[$attribute]['value'], + $this->operation_tags[$attribute]['systag'] ); - $i = 0; - $headers = array(); - unset($this->serveroutput->headers); - $http->ReadReplyHeaders($headers); - self::_putDebug("H T T P R E S P O N S E :"); - self::_putDebug("Response headers:"); - for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) - { - $header_name = Key($headers); - if (GetType($headers[$header_name]) == "array") - { - for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) - { - self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]); - $this->serveroutput->headers[$i] = - $header_name . ": " - . $headers[$header_name][$header_value]; - $i++; - } - } - else - { - self::_putDebug($header_name . ": " . $headers[$header_name]); - $this->serveroutput->headers[$i] = - $header_name - . ": " - . $headers[$header_name]; - $i++; - } + } + elseif (in_array($attribute, $job_attributes_tags)) + { + unset( + $this->job_tags[$attribute]['value'], + $this->job_tags[$attribute]['systag'] + ); + } + elseif (in_array($attribute, $printer_attributes_tags)) + { + unset( + $this->printer_tags[$attribute]['value'], + $this->printer_tags[$attribute]['systag'] + ); + } + else + { + trigger_error( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , E_USER_NOTICE); + self::_putDebug( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 3); + self::_errorLog( + sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'), + $attribute) , 2); + return FALSE; + } + return true; } - self::_putDebug("\n\nResponse body:\n"); - $this->serveroutput->body = ""; - for (;;) - { - $http->ReadReplyBody($body, 1024); - if (strlen($body) == 0) break; - self::_putDebug(htmlentities($body)); - $this->serveroutput->body.= $body; - } - self::_putDebug("********* END RESPONSE BODY ********"); - } - } - $http->Close(); - return true; - } - - // - // INIT - // - - protected function _initTags() - { - $this->tags_types = array( - "unsupported" => array( - "tag" => chr(0x10) , - "build" => "" - ) , - "reserved" => array( - "tag" => chr(0x11) , - "build" => "" - ) , - "unknown" => array( - "tag" => chr(0x12) , - "build" => "" - ) , - "no-value" => array( - "tag" => chr(0x13) , - "build" => "no_value" - ) , - "integer" => array( - "tag" => chr(0x21) , - "build" => "integer" - ) , - "boolean" => array( - "tag" => chr(0x22) , - "build" => "boolean" - ) , - "enum" => array( - "tag" => chr(0x23) , - "build" => "enum" - ) , - "octetString" => array( - "tag" => chr(0x30) , - "build" => "octet_string" - ) , - "datetime" => array( - "tag" => chr(0x31) , - "build" => "datetime" - ) , - "resolution" => array( - "tag" => chr(0x32) , - "build" => "resolution" - ) , - "rangeOfInteger" => array( - "tag" => chr(0x33) , - "build" => "range_of_integers" - ) , - "textWithLanguage" => array( - "tag" => chr(0x35) , - "build" => "string" - ) , - "nameWithLanguage" => array( - "tag" => chr(0x36) , - "build" => "string" - ) , - /* - "text" => array ("tag" => chr(0x40), - "build" => "string"), - "text string" => array ("tag" => chr(0x40), - "build" => "string"), + // + // LOGGING / DEBUGGING + // + /** + * Sets log file destination. Creates the file if has permission. + * + * @param string $log_destination + * @param string $destination_type + * @param int $level + * + * @throws ippException */ - "textWithoutLanguage" => array( - "tag" => chr(0x41) , - "build" => "string" - ) , - "nameWithoutLanguage" => array( - "tag" => chr(0x42) , - "buid" => "string" - ) , - "keyword" => array( - "tag" => chr(0x44) , - "build" => "string" - ) , - "uri" => array( - "tag" => chr(0x45) , - "build" => "string" - ) , - "uriScheme" => array( - "tag" => chr(0x46) , - "build" => "string" - ) , - "charset" => array( - "tag" => chr(0x47) , - "build" => "string" - ) , - "naturalLanguage" => array( - "tag" => chr(0x48) , - "build" => "string" - ) , - "mimeMediaType" => array( - "tag" => chr(0x49) , - "build" => "string" - ) , - "extendedAttributes" => array( - "tag" => chr(0x7F) , - "build" => "extended" - ) , - ); - $this->operation_tags = array( - "compression" => array( - "tag" => "keyword" - ) , - "document-natural-language" => array( - "tag" => "naturalLanguage" - ) , - "job-k-octets" => array( - "tag" => "integer" - ) , - "job-impressions" => array( - "tag" => "integer" - ) , - "job-media-sheets" => array( - "tag" => "integer" - ) , - ); - $this->job_tags = array( - "job-priority" => array( - "tag" => "integer" - ) , - "job-hold-until" => array( - "tag" => "keyword" - ) , - "job-sheets" => array( - "tag" => "keyword" - ) , //banner page - "multiple-document-handling" => array( - "tag" => "keyword" - ) , - //"copies" => array("tag" => "integer"), - "finishings" => array( - "tag" => "enum" - ) , - //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function - //"sides" => array("tag" => "keyword"), // has its own function - "number-up" => array( - "tag" => "integer" - ) , - "orientation-requested" => array( - "tag" => "enum" - ) , - "media" => array( - "tag" => "keyword" - ) , - "printer-resolution" => array( - "tag" => "resolution" - ) , - "print-quality" => array( - "tag" => "enum" - ) , - "job-message-from-operator" => array( - "tag" => "textWithoutLanguage" - ) , - ); - $this->printer_tags = array( - "requested-attributes" => array( - "tag" => "keyword" - ) - ); - } - - // - // SETUP - // - - protected function _setOperationId() - { - $prepend = ''; - $this->operation_id+= 1; - $this->meta->operation_id = self::_integerBuild($this->operation_id); - self::_putDebug("operation id is: " . $this->operation_id, 2); - } - - protected function _setJobId() - { - $this->meta->jobid+= 1; - $prepend = ''; - $prepend_length = 4 - strlen($this->meta->jobid); - for ($i = 0; $i < $prepend_length; $i++) $prepend.= '0'; - return $prepend . $this->meta->jobid; - } - - protected function _setJobUri($job_uri) - { - $this->meta->job_uri = chr(0x45) // type uri - . chr(0x00) . chr(0x07) // name-length - . "job-uri" - //. chr(0x00).chr(strlen($job_uri)) - . self::_giveMeStringLength($job_uri) . $job_uri; - self::_putDebug("job-uri is: " . $job_uri, 2); - } - - // - // RESPONSE PARSING - // - - protected function _parseServerOutput() - { - $this->serveroutput->response = array(); - if (!self::_parseHttpHeaders()) return FALSE; - $this->_parsing->offset = 0; - self::_parseIppVersion(); - self::_parseStatusCode(); - self::_parseRequestID(); - $this->_parseResponse(); - //devel - self::_putDebug( - sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status), - 4); - self::_putDebug("****** END OF OPERATION ****"); - return true; - } - - protected function _parseHttpHeaders() - { - $response = ""; - switch ($this->serveroutput->headers[0]) - { - case "http/1.1 200 ok: ": - $this->serveroutput->httpstatus = "HTTP/1.1 200 OK"; - $response = "OK"; - break; - - // primitive http/1.0 for Lexmark printers (from Rick Baril) - case "http/1.0 200 ok: ": - $this->serveroutput->httpstatus = "HTTP/1.0 200 OK"; - $response = "OK"; - break; - - case "http/1.1 100 continue: ": - $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE"; - $response = "OK"; - break; - - case "": - $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server"; - $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER"; - trigger_error("No Response From Server", E_USER_WARNING); - self::_errorLog("No Response From Server", 1); - $this->disconnected = 1; - return FALSE; - break; - - default: - $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]); - #$strings = split(' ', $server_response, 3); - $strings = preg_split('# #', $server_response, 3); - $errno = $strings[1]; - $string = strtoupper(str_replace(' ', '_', $strings[2])); - trigger_error( - sprintf(_("server responds %s") , $server_response), - E_USER_WARNING); - self::_errorLog("server responds " . $server_response, 1); - $this->serveroutput->httpstatus = - strtoupper($strings[0]) - . " " - . $errno - . " " - . ucfirst($strings[2]); - - $this->serveroutput->status = - "HTTP-ERROR-" - . $errno - . "-" - . $string; - $this->disconnected = 1; - return FALSE; - break; - } - unset($this->serveroutput->headers); - return TRUE; - } - - protected function _parseIppVersion() - { - $ippversion = - (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) - + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - switch ($ippversion) - { - case 0x0101: - $this->serveroutput->ipp_version = "1.1"; - break; - - default: - $this->serveroutput->ipp_version = - sprintf("%u.%u (Unknown)", - ord($this->serveroutput->body[$this->_parsing->offset]) * 256, - ord($this->serveroutput->body[$this->_parsing->offset + 1])); - break; - } - self::_putDebug("I P P R E S P O N S E :\n\n"); - self::_putDebug( - sprintf("IPP version %s%s: %s", - ord($this->serveroutput->body[$this->_parsing->offset]), - ord($this->serveroutput->body[$this->_parsing->offset + 1]), - $this->serveroutput->ipp_version)); - $this->_parsing->offset+= 2; - return; - } - - protected function _parseStatusCode() - { - $status_code = - (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) - + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - $this->serveroutput->status = "NOT PARSED"; - $this->_parsing->offset+= 2; - if (strlen($this->serveroutput->body) < $this->_parsing->offset) - { - return false; - } - if ($status_code < 0x00FF) - { - $this->serveroutput->status = "successfull"; - } - elseif ($status_code < 0x01FF) - { - $this->serveroutput->status = "informational"; - } - elseif ($status_code < 0x02FF) - { - $this->serveroutput->status = "redirection"; - } - elseif ($status_code < 0x04FF) - { - $this->serveroutput->status = "client-error"; - } - elseif ($status_code < 0x05FF) - { - $this->serveroutput->status = "server-error"; - } - switch ($status_code) - { - case 0x0000: - $this->serveroutput->status = "successfull-ok"; - break; - - case 0x0001: - $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes"; - break; - - case 0x002: - $this->serveroutput->status = "successful-ok-conflicting-attributes"; - break; - - case 0x0400: - $this->serveroutput->status = "client-error-bad-request"; - break; - - case 0x0401: - $this->serveroutput->status = "client-error-forbidden"; - break; - - case 0x0402: - $this->serveroutput->status = "client-error-not-authenticated"; - break; - - case 0x0403: - $this->serveroutput->status = "client-error-not-authorized"; - break; - - case 0x0404: - $this->serveroutput->status = "client-error-not-possible"; - break; - - case 0x0405: - $this->serveroutput->status = "client-error-timeout"; - break; - - case 0x0406: - $this->serveroutput->status = "client-error-not-found"; - break; - - case 0x0407: - $this->serveroutput->status = "client-error-gone"; - break; - - case 0x0408: - $this->serveroutput->status = "client-error-request-entity-too-large"; - break; - - case 0x0409: - $this->serveroutput->status = "client-error-request-value-too-long"; - break; - - case 0x040A: - $this->serveroutput->status = "client-error-document-format-not-supported"; - break; - - case 0x040B: - $this->serveroutput->status = "client-error-attributes-or-values-not-supported"; - break; - - case 0x040C: - $this->serveroutput->status = "client-error-uri-scheme-not-supported"; - break; - - case 0x040D: - $this->serveroutput->status = "client-error-charset-not-supported"; - break; - - case 0x040E: - $this->serveroutput->status = "client-error-conflicting-attributes"; - break; - - case 0x040F: - $this->serveroutput->status = "client-error-compression-not-supported"; - break; - - case 0x0410: - $this->serveroutput->status = "client-error-compression-error"; - break; - - case 0x0411: - $this->serveroutput->status = "client-error-document-format-error"; - break; - - case 0x0412: - $this->serveroutput->status = "client-error-document-access-error"; - break; - - case 0x0413: // RFC3380 - $this->serveroutput->status = "client-error-attributes-not-settable"; - break; - - case 0x0500: - $this->serveroutput->status = "server-error-internal-error"; - break; - - case 0x0501: - $this->serveroutput->status = "server-error-operation-not-supported"; - break; - - case 0x0502: - $this->serveroutput->status = "server-error-service-unavailable"; - break; - - case 0x0503: - $this->serveroutput->status = "server-error-version-not-supported"; - break; - - case 0x0504: - $this->serveroutput->status = "server-error-device-error"; - break; - - case 0x0505: - $this->serveroutput->status = "server-error-temporary-error"; - break; - - case 0x0506: - $this->serveroutput->status = "server-error-not-accepting-jobs"; - break; - - case 0x0507: - $this->serveroutput->status = "server-error-busy"; - break; - - case 0x0508: - $this->serveroutput->status = "server-error-job-canceled"; - break; - - case 0x0509: - $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported"; - break; - - default: - break; - } - self::_putDebug( - sprintf( - "status-code: %s%s: %s ", - $this->serveroutput->body[$this->_parsing->offset], - $this->serveroutput->body[$this->_parsing->offset + 1], - $this->serveroutput->status), - 4); - return; - } - - protected function _parseRequestID() - { - $this->serveroutput->request_id = - self::_interpretInteger( - substr($this->serveroutput->body, $this->_parsing->offset, 4) - ); - self::_putDebug("request-id " . $this->serveroutput->request_id, 2); - $this->_parsing->offset+= 4; - return; - } - - protected function _interpretInteger($value) - { - // they are _signed_ integers - $value_parsed = 0; - for ($i = strlen($value); $i > 0; $i --) - { - $value_parsed += - ( - (1 << (($i - 1) * 8)) - * - ord($value[strlen($value) - $i]) - ); - - } - if ($value_parsed >= 2147483648) - { - $value_parsed -= 4294967296; - } - return $value_parsed; - } - - protected function _parseResponse() - { - } - - // - // REQUEST BUILDING - // - - protected function _stringJob() - { - if (!isset($this->setup->charset)) self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) self::setBinary(); - if (!isset($this->setup->uri)) - { - $this->getPrinters(); - unset($this->jobs[count($this->jobs) - 1]); - unset($this->jobs_uri[count($this->jobs_uri) - 1]); - unset($this->status[count($this->status) - 1]); - if (array_key_exists(0, $this->available_printers)) - { - self::setPrinterURI($this->available_printers[0]); - } - else - { - trigger_error( - _("_stringJob: Printer URI is not set: die"), - E_USER_WARNING); - self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4); - self::_errorLog(" Printer URI is not set, die", 2); - return FALSE; - } - } - if (!isset($this->setup->copies)) self::setCopies(1); - if (!isset($this->setup->language)) self::setLanguage('en_us'); - if (!isset($this->setup->mime_media_type)) self::setMimeMediaType(); - if (!isset($this->setup->jobname)) self::setJobName(); - unset($this->setup->jobname); - if (!isset($this->meta->username)) self::setUserName(); - if (!isset($this->meta->fidelity)) $this->meta->fidelity = ''; - if (!isset($this->meta->document_name)) $this->meta->document_name = ''; - if (!isset($this->meta->sides)) $this->meta->sides = ''; - if (!isset($this->meta->page_ranges)) $this->meta->page_ranges = ''; - $jobattributes = ''; - $operationattributes = ''; - $printerattributes = ''; - $this->_buildValues($operationattributes, $jobattributes, $printerattributes); - self::_setOperationId(); - if (!isset($this->error_generation->request_body_malformed)) - { - $this->error_generation->request_body_malformed = ""; - } - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number - . chr(0x00) . chr(0x02) // Print-Job | operation-id - . $this->meta->operation_id // request-id - . chr(0x01) // start operation-attributes | operation-attributes-tag - . $this->meta->charset - . $this->meta->language - . $this->meta->printer_uri - . $this->meta->username - . $this->meta->jobname - . $this->meta->fidelity - . $this->meta->document_name - . $this->meta->mime_media_type - . $operationattributes; - if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) - { - $this->stringjob .= - chr(0x02) // start job-attributes | job-attributes-tag - . $this->meta->copies - . $this->meta->sides - . $this->meta->page_ranges - . $jobattributes - ; - } - $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( - sprintf(_("String sent to the server is: %s"), - $this->stringjob) - ); - return TRUE; - } - - protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) - { - $operationattributes = ''; - foreach($this->operation_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + public function setLog($log_destination, $destination_type = 'file', $level = 2) { - if ($item == 0) - { - $operationattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $operationattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + if (!file_exists($log_destination) && is_writable(dirname($log_destination))) + { + touch($log_destination); + chmod($log_destination, 0777); + } + + switch ($destination_type) + { + case 'file': + case 3: + $this->log_destination = $log_destination; + $this->log_type = 3; + break; + + case 'logger': + case 0: + $this->log_destination = ''; + $this->log_type = 0; + break; + + case 'e-mail': + case 1: + $this->log_destination = $log_destination; + $this->log_type = 1; + break; + } + $this->log_level = $level; } - } - } - $jobattributes = ''; - foreach($this->job_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function printDebug() { - if ($item == 0) - { - $jobattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $jobattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + for ($i = 0; $i < $this->debug_count; $i++) + { + echo $this->debug[$i], "\n"; + } + $this->debug = array(); + $this->debug_count = 0; } - } - } - $printerattributes = ''; - foreach($this->printer_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function getDebug() { - if ($item == 0) - { - $printerattributes .= - $values['systag'] - . self::_giveMeStringLength($key) - . $key - . self::_giveMeStringLength($item_value) - . $item_value; - } - else - { - $printerattributes .= - $values['systag'] - . self::_giveMeStringLength('') - . self::_giveMeStringLength($item_value) - . $item_value; - } - $item++; + $debug = ''; + for ($i = 0; $i < $this->debug_count; $i++) + { + $debug.= $this->debug[$i]; + } + $this->debug = array(); + $this->debug_count = 0; + return $debug; } - } - } - reset($this->job_tags); - reset($this->operation_tags); - reset($this->printer_tags); - return true; - } - protected function _giveMeStringLength($string) - { - $length = strlen($string); - if ($length > ((0xFF << 8) + 0xFF) ) - { - $errmsg = sprintf ( - _('max string length for an ipp meta-information = %d, while here %d'), - ((0xFF << 8) + 0xFF), $length); - - if ($this->with_exceptions) - { - throw new ippException($errmsg); - } - else - { - trigger_error ($errmsg, E_USER_ERROR); - } - } - $int1 = $length & 0xFF; - $length -= $int1; - $length = $length >> 8; - $int2 = $length & 0xFF; - return chr($int2) . chr($int1); - } - - protected function _enumBuild($tag, $value) - { - switch ($tag) - { - case "orientation-requested": - switch ($value) + // + // OPERATIONS + // + public function printJob() { - case 'portrait': - $value = chr(3); - break; - - case 'landscape': - $value = chr(4); - break; - - case 'reverse-landscape': - $value = chr(5); - break; - - case 'reverse-portrait': - $value = chr(6); - break; - } - break; - - case "print-quality": - switch ($value) - { - case 'draft': - $value = chr(3); - break; - - case 'normal': - $value = chr(4); - break; - - case 'high': - $value = chr(5); - break; - } - break; - - case "finishing": - switch ($value) - { - case 'none': - $value = chr(3); - break; - - case 'staple': - $value = chr(4); - break; - - case 'punch': - $value = chr(5); - break; - - case 'cover': - $value = chr(6); - break; - - case 'bind': - $value = chr(7); - break; - - case 'saddle-stitch': - $value = chr(8); - break; - - case 'edge-stitch': - $value = chr(9); - break; - - case 'staple-top-left': - $value = chr(20); - break; - - case 'staple-bottom-left': - $value = chr(21); - break; - - case 'staple-top-right': - $value = chr(22); - break; - - case 'staple-bottom-right': - $value = chr(23); - break; - - case 'edge-stitch-left': - $value = chr(24); - break; - - case 'edge-stitch-top': - $value = chr(25); - break; - - case 'edge-stitch-right': - $value = chr(26); - break; - - case 'edge-stitch-bottom': - $value = chr(27); - break; - - case 'staple-dual-left': - $value = chr(28); - break; - - case 'staple-dual-top': - $value = chr(29); - break; - - case 'staple-dual-right': - $value = chr(30); - break; - - case 'staple-dual-bottom': - $value = chr(31); - break; - } - break; - } - $prepend = ''; - while ((strlen($value) + strlen($prepend)) < 4) - { - $prepend .= chr(0); - } - return $prepend . $value; - } - - protected function _integerBuild($value) - { - if ($value >= 2147483647 || $value < - 2147483648) - { - trigger_error( - _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING); - return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00); - } - $initial_value = $value; - $int1 = $value & 0xFF; - $value -= $int1; - $value = $value >> 8; - $int2 = $value & 0xFF; - $value-= $int2; - $value = $value >> 8; - $int3 = $value & 0xFF; - $value-= $int3; - $value = $value >> 8; - $int4 = $value & 0xFF; //64bits - if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); - else $int4 = chr($int4); - $value = $int4 . chr($int3) . chr($int2) . chr($int1); - return $value; - } - - protected function _rangeOfIntegerBuild($integers) - { - #$integers = split(":", $integers); - $integers = preg_split("#:#", $integers); - for ($i = 0; $i < 2; $i++) $outvalue[$i] = self::_integerBuild($integers[$i]); - return $outvalue[0] . $outvalue[1]; - } - - protected function _setJobAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->job_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->job_tags[$attribute]['value'][] = self::_integerBuild($value); - break; - - case 'nameWithoutLanguage': - case 'nameWithLanguage': - case 'textWithoutLanguage': - case 'textWithLanguage': - case 'keyword': - case 'naturalLanguage': - $this->job_tags[$attribute]['value'][] = $value; - break; - - case 'enum': - $value = $this->_enumBuild($attribute, $value); // may be overwritten by children - $this->job_tags[$attribute]['value'][] = $value; - break; - - case 'rangeOfInteger': - // $value have to be: INT1:INT2 , eg 100:1000 - $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value); - break; - - case 'resolution': - if (preg_match("#dpi#", $value)) $unit = chr(0x3); - if (preg_match("#dpc#", $value)) $unit = chr(0x4); - $search = array( - "#(dpi|dpc)#", - '#(x|-)#' + // this BASIC version of printJob do not parse server + // output for job's attributes + self::_putDebug( + sprintf( + "************** Date: %s ***********", + date('Y-m-d H:i:s') + ) + ); + if (!$this->_stringJob()) { + return FALSE; + } + if (is_readable($this->data)) + { + self::_putDebug(_("Printing a FILE")); + $this->output = $this->stringjob; + if ($this->setup->datatype == "TEXT") + { + $this->output.= chr(0x16); + } + $post_values = array( + "Content-Type" => "application/ipp", + "Data" => $this->output, + "File" => $this->data ); - $replace = array( - "", - ":" - ); - $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit; - $this->job_tags[$attribute]['value'][] = $value; - break; + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { + $post_values = array_merge( + $post_values, + array( + "Filetype" => "TEXT" + ) + ); + } + } + else + { + self::_putDebug(_("Printing DATA")); + $this->output = + $this->stringjob + . $this->datahead + . $this->data + . $this->datatail; + $post_values = array( + "Content-Type" => "application/ipp", + "Data" => $this->output + ); + } + if (self::_sendHttp($post_values, $this->paths["printers"])) + { + self::_parseServerOutput(); + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status, array( + $this->serveroutput->status + )); + if ($this->serveroutput->status == "successfull-ok") + { + self::_errorLog( + sprintf("printing job %s: ", $this->last_job) + . $this->serveroutput->status, + 3); + } + else + { + self::_errorLog( + sprintf("printing job: ", $this->last_job) + . $this->serveroutput->status, + 1); + } + return $this->serveroutput->status; + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + $this->status = + array_merge($this->status, array("OPERATION FAILED")); + $this->jobs = + array_merge($this->jobs, array("")); + $this->jobs_uri = + array_merge($this->jobs_uri, array("")); - protected function _setOperationAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->operation_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value); - break; + self::_errorLog("printing job : OPERATION FAILED", 1); + return false; + } - case 'keyword': - case 'naturalLanguage': - $this->operation_tags[$attribute]['value'][] = $value; - break; + // + // HTTP OUTPUT + // + protected function _sendHttp($post_values, $uri) + { + /* + This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos + */ + $this->response_completed[] = "no"; + unset($this->serverouptut); + self::_putDebug(_("Processing HTTP request") , 2); + $this->serveroutput->headers = array(); + $this->serveroutput->body = ""; + $http = new http_class; + if (!$this->unix) { + $http->host = $this->host; + } + else { + $http->host = "localhost"; + } + $http->with_exceptions = $this->with_exceptions; + if ($this->debug_http) + { + $http->debug = 1; + $http->html_debug = 0; + } + else + { + $http->debug = 0; + $http->html_debug = 0; + } + $url = "http://" . $this->host; + if ($this->ssl) { + $url = "https://" . $this->host; + } + if ($this->unix) { + $url = "unix://" . $this->host; + } + $http->port = $this->port; + $http->timeout = $this->http_timeout; + $http->data_timeout = $this->http_data_timeout; + $http->force_multipart_form_post = false; + $http->user = $this->username; + $http->password = $this->password; + $error = $http->GetRequestArguments($url, $arguments); + $arguments["RequestMethod"] = "POST"; + $arguments["Headers"] = array( + "Content-Type" => "application/ipp" + ); + $arguments["BodyStream"] = array( + array( + "Data" => $post_values["Data"] + ) + ); + if (isset($post_values["File"])) { + $arguments["BodyStream"][] = array( + "File" => $post_values["File"] + ); + } + if (isset($post_values["FileType"]) + && !strcmp($post_values["FileType"], "TEXT") + ) + { + $arguments["BodyStream"][] = array("Data" => Chr(12)); + } + $arguments["RequestURI"] = $uri; + if ($this->with_exceptions && $this->handle_http_exceptions) + { + try + { + $success = $http->Open($arguments); + } + catch(httpException $e) + { + throw new ippException( + sprintf("http error: %s", $e->getMessage()), + $e->getErrno()); + } + } + else + { + $success = $http->Open($arguments); + } + if ($success[0] == true) + { + $success = $http->SendRequest($arguments); + if ($success[0] == true) + { + self::_putDebug("H T T P R E Q U E S T :"); + self::_putDebug("Request headers:"); + for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) + { + $header_name = Key($http->request_headers); + if (GetType($http->request_headers[$header_name]) == "array") + { + for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++) + { + self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]); + } + } + else + { + self::_putDebug($header_name . ": " . $http->request_headers[$header_name]); + } + } + self::_putDebug("Request body:"); + self::_putDebug( + htmlspecialchars($http->request_body) + . "*********** END REQUEST BODY *********" + ); + $i = 0; + $headers = array(); + unset($this->serveroutput->headers); + $http->ReadReplyHeaders($headers); + self::_putDebug("H T T P R E S P O N S E :"); + self::_putDebug("Response headers:"); + for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) + { + $header_name = Key($headers); + if (GetType($headers[$header_name]) == "array") + { + for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) + { + self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]); + $this->serveroutput->headers[$i] = + $header_name . ": " + . $headers[$header_name][$header_value]; + $i++; + } + } + else + { + self::_putDebug($header_name . ": " . $headers[$header_name]); + $this->serveroutput->headers[$i] = + $header_name + . ": " + . $headers[$header_name]; + $i++; + } + } + self::_putDebug("\n\nResponse body:\n"); + $this->serveroutput->body = ""; + for (;;) + { + $http->ReadReplyBody($body, 1024); + if (strlen($body) == 0) { + break; + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + self::_putDebug(htmlentities($body)); + $this->serveroutput->body.= $body; + } + self::_putDebug("********* END RESPONSE BODY ********"); + } + } + $http->Close(); + return true; + } - protected function _setPrinterAttribute($attribute, $value) - { - //used by setAttribute - $tag_type = $this->printer_tags[$attribute]['tag']; - switch ($tag_type) - { - case 'integer': - $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value); - break; + // + // INIT + // + protected function _initTags() + { + $this->tags_types = array( + "unsupported" => array( + "tag" => chr(0x10) , + "build" => "" + ) , + "reserved" => array( + "tag" => chr(0x11) , + "build" => "" + ) , + "unknown" => array( + "tag" => chr(0x12) , + "build" => "" + ) , + "no-value" => array( + "tag" => chr(0x13) , + "build" => "no_value" + ) , + "integer" => array( + "tag" => chr(0x21) , + "build" => "integer" + ) , + "boolean" => array( + "tag" => chr(0x22) , + "build" => "boolean" + ) , + "enum" => array( + "tag" => chr(0x23) , + "build" => "enum" + ) , + "octetString" => array( + "tag" => chr(0x30) , + "build" => "octet_string" + ) , + "datetime" => array( + "tag" => chr(0x31) , + "build" => "datetime" + ) , + "resolution" => array( + "tag" => chr(0x32) , + "build" => "resolution" + ) , + "rangeOfInteger" => array( + "tag" => chr(0x33) , + "build" => "range_of_integers" + ) , + "textWithLanguage" => array( + "tag" => chr(0x35) , + "build" => "string" + ) , + "nameWithLanguage" => array( + "tag" => chr(0x36) , + "build" => "string" + ) , + /* + "text" => array ("tag" => chr(0x40), + "build" => "string"), + "text string" => array ("tag" => chr(0x40), + "build" => "string"), + */ + "textWithoutLanguage" => array( + "tag" => chr(0x41) , + "build" => "string" + ) , + "nameWithoutLanguage" => array( + "tag" => chr(0x42) , + "buid" => "string" + ) , + "keyword" => array( + "tag" => chr(0x44) , + "build" => "string" + ) , + "uri" => array( + "tag" => chr(0x45) , + "build" => "string" + ) , + "uriScheme" => array( + "tag" => chr(0x46) , + "build" => "string" + ) , + "charset" => array( + "tag" => chr(0x47) , + "build" => "string" + ) , + "naturalLanguage" => array( + "tag" => chr(0x48) , + "build" => "string" + ) , + "mimeMediaType" => array( + "tag" => chr(0x49) , + "build" => "string" + ) , + "extendedAttributes" => array( + "tag" => chr(0x7F) , + "build" => "extended" + ) , + ); + $this->operation_tags = array( + "compression" => array( + "tag" => "keyword" + ) , + "document-natural-language" => array( + "tag" => "naturalLanguage" + ) , + "job-k-octets" => array( + "tag" => "integer" + ) , + "job-impressions" => array( + "tag" => "integer" + ) , + "job-media-sheets" => array( + "tag" => "integer" + ) , + ); + $this->job_tags = array( + "job-priority" => array( + "tag" => "integer" + ) , + "job-hold-until" => array( + "tag" => "keyword" + ) , + "job-sheets" => array( + "tag" => "keyword" + ) , //banner page + "multiple-document-handling" => array( + "tag" => "keyword" + ) , + //"copies" => array("tag" => "integer"), + "finishings" => array( + "tag" => "enum" + ) , + //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function + //"sides" => array("tag" => "keyword"), // has its own function + "number-up" => array( + "tag" => "integer" + ) , + "orientation-requested" => array( + "tag" => "enum" + ) , + "media" => array( + "tag" => "keyword" + ) , + "printer-resolution" => array( + "tag" => "resolution" + ) , + "print-quality" => array( + "tag" => "enum" + ) , + "job-message-from-operator" => array( + "tag" => "textWithoutLanguage" + ) , + ); + $this->printer_tags = array( + "requested-attributes" => array( + "tag" => "keyword" + ) + ); + } - case 'keyword': - case 'naturalLanguage': - $this->printer_tags[$attribute]['value'][] = $value; - break; + // + // SETUP + // + protected function _setOperationId() + { + $prepend = ''; + $this->operation_id+= 1; + $this->meta->operation_id = self::_integerBuild($this->operation_id); + self::_putDebug("operation id is: " . $this->operation_id, 2); + } - default: - trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); - self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); - return FALSE; - break; - } - $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; - } + protected function _setJobId() + { + $this->meta->jobid+= 1; + $prepend = ''; + $prepend_length = 4 - strlen($this->meta->jobid); + for ($i = 0; $i < $prepend_length; $i++) { + $prepend.= '0'; + } + return $prepend . $this->meta->jobid; + } - // - // DEBUGGING - // - protected function _putDebug($string, $level = 1) - { - if ($level === false) return; - if ($level < $this->debug_level) return; - $this->debug[$this->debug_count] = substr($string, 0, 1024); - $this->debug_count++; - //$this->debug .= substr($string,0,1024); + protected function _setJobUri($job_uri) + { + $this->meta->job_uri = chr(0x45) // type uri + . chr(0x00) . chr(0x07) // name-length + . "job-uri" + //. chr(0x00).chr(strlen($job_uri)) + . self::_giveMeStringLength($job_uri) . $job_uri; + self::_putDebug("job-uri is: " . $job_uri, 2); + } - } + // + // RESPONSE PARSING + // + protected function _parseServerOutput() + { + $this->serveroutput->response = array(); + if (!self::_parseHttpHeaders()) { + return FALSE; + } + $this->_parsing->offset = 0; + self::_parseIppVersion(); + self::_parseStatusCode(); + self::_parseRequestID(); + $this->_parseResponse(); + //devel + self::_putDebug( + sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status), + 4); + self::_putDebug("****** END OF OPERATION ****"); + return true; + } - // - // LOGGING - // - protected function _errorLog($string_to_log, $level) - { - if ($level < $this->log_level) return; - $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); - if ($this->log_type == 0) - { - error_log($string); - return; - } - $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); - error_log($string, $this->log_type, $this->log_destination); - return; - } + protected function _parseHttpHeaders() + { + $response = ""; + switch ($this->serveroutput->headers[0]) + { + case "http/1.1 200 ok: ": + $this->serveroutput->httpstatus = "HTTP/1.1 200 OK"; + $response = "OK"; + break; -}; -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> + // primitive http/1.0 for Lexmark printers (from Rick Baril) + case "http/1.0 200 ok: ": + $this->serveroutput->httpstatus = "HTTP/1.0 200 OK"; + $response = "OK"; + break; + + case "http/1.1 100 continue: ": + $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE"; + $response = "OK"; + break; + + case "": + $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server"; + $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER"; + trigger_error("No Response From Server", E_USER_WARNING); + self::_errorLog("No Response From Server", 1); + $this->disconnected = 1; + return FALSE; + break; + + default: + $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]); + #$strings = split(' ', $server_response, 3); + $strings = preg_split('# #', $server_response, 3); + $errno = $strings[1]; + $string = strtoupper(str_replace(' ', '_', $strings[2])); + trigger_error( + sprintf(_("server responds %s") , $server_response), + E_USER_WARNING); + self::_errorLog("server responds " . $server_response, 1); + $this->serveroutput->httpstatus = + strtoupper($strings[0]) + . " " + . $errno + . " " + . ucfirst($strings[2]); + + $this->serveroutput->status = + "HTTP-ERROR-" + . $errno + . "-" + . $string; + $this->disconnected = 1; + return FALSE; + break; + } + unset($this->serveroutput->headers); + return TRUE; + } + + protected function _parseIppVersion() + { + $ippversion = + (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) + + ord($this->serveroutput->body[$this->_parsing->offset + 1]); + switch ($ippversion) + { + case 0x0101: + $this->serveroutput->ipp_version = "1.1"; + break; + + default: + $this->serveroutput->ipp_version = + sprintf("%u.%u (Unknown)", + ord($this->serveroutput->body[$this->_parsing->offset]) * 256, + ord($this->serveroutput->body[$this->_parsing->offset + 1])); + break; + } + self::_putDebug("I P P R E S P O N S E :\n\n"); + self::_putDebug( + sprintf("IPP version %s%s: %s", + ord($this->serveroutput->body[$this->_parsing->offset]), + ord($this->serveroutput->body[$this->_parsing->offset + 1]), + $this->serveroutput->ipp_version)); + $this->_parsing->offset+= 2; + return; + } + + protected function _parseStatusCode() + { + $status_code = + (ord($this->serveroutput->body[$this->_parsing->offset]) * 256) + + ord($this->serveroutput->body[$this->_parsing->offset + 1]); + $this->serveroutput->status = "NOT PARSED"; + $this->_parsing->offset+= 2; + if (strlen($this->serveroutput->body) < $this->_parsing->offset) + { + return false; + } + if ($status_code < 0x00FF) + { + $this->serveroutput->status = "successfull"; + } + elseif ($status_code < 0x01FF) + { + $this->serveroutput->status = "informational"; + } + elseif ($status_code < 0x02FF) + { + $this->serveroutput->status = "redirection"; + } + elseif ($status_code < 0x04FF) + { + $this->serveroutput->status = "client-error"; + } + elseif ($status_code < 0x05FF) + { + $this->serveroutput->status = "server-error"; + } + switch ($status_code) + { + case 0x0000: + $this->serveroutput->status = "successfull-ok"; + break; + + case 0x0001: + $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes"; + break; + + case 0x002: + $this->serveroutput->status = "successful-ok-conflicting-attributes"; + break; + + case 0x0400: + $this->serveroutput->status = "client-error-bad-request"; + break; + + case 0x0401: + $this->serveroutput->status = "client-error-forbidden"; + break; + + case 0x0402: + $this->serveroutput->status = "client-error-not-authenticated"; + break; + + case 0x0403: + $this->serveroutput->status = "client-error-not-authorized"; + break; + + case 0x0404: + $this->serveroutput->status = "client-error-not-possible"; + break; + + case 0x0405: + $this->serveroutput->status = "client-error-timeout"; + break; + + case 0x0406: + $this->serveroutput->status = "client-error-not-found"; + break; + + case 0x0407: + $this->serveroutput->status = "client-error-gone"; + break; + + case 0x0408: + $this->serveroutput->status = "client-error-request-entity-too-large"; + break; + + case 0x0409: + $this->serveroutput->status = "client-error-request-value-too-long"; + break; + + case 0x040A: + $this->serveroutput->status = "client-error-document-format-not-supported"; + break; + + case 0x040B: + $this->serveroutput->status = "client-error-attributes-or-values-not-supported"; + break; + + case 0x040C: + $this->serveroutput->status = "client-error-uri-scheme-not-supported"; + break; + + case 0x040D: + $this->serveroutput->status = "client-error-charset-not-supported"; + break; + + case 0x040E: + $this->serveroutput->status = "client-error-conflicting-attributes"; + break; + + case 0x040F: + $this->serveroutput->status = "client-error-compression-not-supported"; + break; + + case 0x0410: + $this->serveroutput->status = "client-error-compression-error"; + break; + + case 0x0411: + $this->serveroutput->status = "client-error-document-format-error"; + break; + + case 0x0412: + $this->serveroutput->status = "client-error-document-access-error"; + break; + + case 0x0413: // RFC3380 + $this->serveroutput->status = "client-error-attributes-not-settable"; + break; + + case 0x0500: + $this->serveroutput->status = "server-error-internal-error"; + break; + + case 0x0501: + $this->serveroutput->status = "server-error-operation-not-supported"; + break; + + case 0x0502: + $this->serveroutput->status = "server-error-service-unavailable"; + break; + + case 0x0503: + $this->serveroutput->status = "server-error-version-not-supported"; + break; + + case 0x0504: + $this->serveroutput->status = "server-error-device-error"; + break; + + case 0x0505: + $this->serveroutput->status = "server-error-temporary-error"; + break; + + case 0x0506: + $this->serveroutput->status = "server-error-not-accepting-jobs"; + break; + + case 0x0507: + $this->serveroutput->status = "server-error-busy"; + break; + + case 0x0508: + $this->serveroutput->status = "server-error-job-canceled"; + break; + + case 0x0509: + $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported"; + break; + + default: + break; + } + self::_putDebug( + sprintf( + "status-code: %s%s: %s ", + $this->serveroutput->body[$this->_parsing->offset], + $this->serveroutput->body[$this->_parsing->offset + 1], + $this->serveroutput->status), + 4); + return; + } + + protected function _parseRequestID() + { + $this->serveroutput->request_id = + self::_interpretInteger( + substr($this->serveroutput->body, $this->_parsing->offset, 4) + ); + self::_putDebug("request-id " . $this->serveroutput->request_id, 2); + $this->_parsing->offset+= 4; + return; + } + + protected function _interpretInteger($value) + { + // they are _signed_ integers + $value_parsed = 0; + for ($i = strlen($value); $i > 0; $i --) + { + $value_parsed += + ( + (1 << (($i - 1) * 8)) + * + ord($value[strlen($value) - $i]) + ); + } + if ($value_parsed >= 2147483648) + { + $value_parsed -= 4294967296; + } + return $value_parsed; + } + + protected function _parseResponse() + { + } + + // + // REQUEST BUILDING + // + protected function _stringJob() + { + if (!isset($this->setup->charset)) { + self::setCharset(); + } + if (!isset($this->setup->datatype)) { + self::setBinary(); + } + if (!isset($this->setup->uri)) + { + $this->getPrinters(); + unset($this->jobs[count($this->jobs) - 1]); + unset($this->jobs_uri[count($this->jobs_uri) - 1]); + unset($this->status[count($this->status) - 1]); + if (array_key_exists(0, $this->available_printers)) + { + self::setPrinterURI($this->available_printers[0]); + } + else + { + trigger_error( + _("_stringJob: Printer URI is not set: die"), + E_USER_WARNING); + self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4); + self::_errorLog(" Printer URI is not set, die", 2); + return FALSE; + } + } + if (!isset($this->setup->copies)) { + self::setCopies(1); + } + if (!isset($this->setup->language)) { + self::setLanguage('en_us'); + } + if (!isset($this->setup->mime_media_type)) { + self::setMimeMediaType(); + } + if (!isset($this->setup->jobname)) { + self::setJobName(); + } + unset($this->setup->jobname); + if (!isset($this->meta->username)) { + self::setUserName(); + } + if (!isset($this->meta->fidelity)) { + $this->meta->fidelity = ''; + } + if (!isset($this->meta->document_name)) { + $this->meta->document_name = ''; + } + if (!isset($this->meta->sides)) { + $this->meta->sides = ''; + } + if (!isset($this->meta->page_ranges)) { + $this->meta->page_ranges = ''; + } + $jobattributes = ''; + $operationattributes = ''; + $printerattributes = ''; + $this->_buildValues($operationattributes, $jobattributes, $printerattributes); + self::_setOperationId(); + if (!isset($this->error_generation->request_body_malformed)) + { + $this->error_generation->request_body_malformed = ""; + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number + . chr(0x00) . chr(0x02) // Print-Job | operation-id + . $this->meta->operation_id // request-id + . chr(0x01) // start operation-attributes | operation-attributes-tag + . $this->meta->charset + . $this->meta->language + . $this->meta->printer_uri + . $this->meta->username + . $this->meta->jobname + . $this->meta->fidelity + . $this->meta->document_name + . $this->meta->mime_media_type + . $operationattributes; + if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) + { + $this->stringjob .= + chr(0x02) // start job-attributes | job-attributes-tag + . $this->meta->copies + . $this->meta->sides + . $this->meta->page_ranges + . $jobattributes; + } + $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag + self::_putDebug( + sprintf(_("String sent to the server is: %s"), + $this->stringjob) + ); + return TRUE; + } + + protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) + { + $operationattributes = ''; + foreach($this->operation_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $operationattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $operationattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + $jobattributes = ''; + foreach($this->job_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $jobattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $jobattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + $printerattributes = ''; + foreach($this->printer_tags as $key => $values) + { + $item = 0; + if (array_key_exists('value', $values)) + { + foreach($values['value'] as $item_value) + { + if ($item == 0) + { + $printerattributes .= + $values['systag'] + . self::_giveMeStringLength($key) + . $key + . self::_giveMeStringLength($item_value) + . $item_value; + } + else + { + $printerattributes .= + $values['systag'] + . self::_giveMeStringLength('') + . self::_giveMeStringLength($item_value) + . $item_value; + } + $item++; + } + } + } + reset($this->job_tags); + reset($this->operation_tags); + reset($this->printer_tags); + return true; + } + + protected function _giveMeStringLength($string) + { + $length = strlen($string); + if ($length > ((0xFF << 8) + 0xFF) ) + { + $errmsg = sprintf ( + _('max string length for an ipp meta-information = %d, while here %d'), + ((0xFF << 8) + 0xFF), $length); + + if ($this->with_exceptions) + { + throw new ippException($errmsg); + } + else + { + trigger_error ($errmsg, E_USER_ERROR); + } + } + $int1 = $length & 0xFF; + $length -= $int1; + $length = $length >> 8; + $int2 = $length & 0xFF; + return chr($int2) . chr($int1); + } + + protected function _enumBuild($tag, $value) + { + switch ($tag) + { + case "orientation-requested": + switch ($value) + { + case 'portrait': + $value = chr(3); + break; + + case 'landscape': + $value = chr(4); + break; + + case 'reverse-landscape': + $value = chr(5); + break; + + case 'reverse-portrait': + $value = chr(6); + break; + } + break; + + case "print-quality": + switch ($value) + { + case 'draft': + $value = chr(3); + break; + + case 'normal': + $value = chr(4); + break; + + case 'high': + $value = chr(5); + break; + } + break; + + case "finishing": + switch ($value) + { + case 'none': + $value = chr(3); + break; + + case 'staple': + $value = chr(4); + break; + + case 'punch': + $value = chr(5); + break; + + case 'cover': + $value = chr(6); + break; + + case 'bind': + $value = chr(7); + break; + + case 'saddle-stitch': + $value = chr(8); + break; + + case 'edge-stitch': + $value = chr(9); + break; + + case 'staple-top-left': + $value = chr(20); + break; + + case 'staple-bottom-left': + $value = chr(21); + break; + + case 'staple-top-right': + $value = chr(22); + break; + + case 'staple-bottom-right': + $value = chr(23); + break; + + case 'edge-stitch-left': + $value = chr(24); + break; + + case 'edge-stitch-top': + $value = chr(25); + break; + + case 'edge-stitch-right': + $value = chr(26); + break; + + case 'edge-stitch-bottom': + $value = chr(27); + break; + + case 'staple-dual-left': + $value = chr(28); + break; + + case 'staple-dual-top': + $value = chr(29); + break; + + case 'staple-dual-right': + $value = chr(30); + break; + + case 'staple-dual-bottom': + $value = chr(31); + break; + } + break; + } + $prepend = ''; + while ((strlen($value) + strlen($prepend)) < 4) + { + $prepend .= chr(0); + } + return $prepend . $value; + } + + protected function _integerBuild($value) + { + if ($value >= 2147483647 || $value < - 2147483648) + { + trigger_error( + _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING); + return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00); + } + $initial_value = $value; + $int1 = $value & 0xFF; + $value -= $int1; + $value = $value >> 8; + $int2 = $value & 0xFF; + $value-= $int2; + $value = $value >> 8; + $int3 = $value & 0xFF; + $value-= $int3; + $value = $value >> 8; + $int4 = $value & 0xFF; //64bits + if ($initial_value < 0) { + $int4 = chr($int4) | chr(0x80); + } + else { + $int4 = chr($int4); + } + $value = $int4 . chr($int3) . chr($int2) . chr($int1); + return $value; + } + + protected function _rangeOfIntegerBuild($integers) + { + #$integers = split(":", $integers); + $integers = preg_split("#:#", $integers); + for ($i = 0; $i < 2; $i++) { + $outvalue[$i] = self::_integerBuild($integers[$i]); + } + return $outvalue[0] . $outvalue[1]; + } + + protected function _setJobAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->job_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->job_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'boolean': + case 'nameWithoutLanguage': + case 'nameWithLanguage': + case 'textWithoutLanguage': + case 'textWithLanguage': + case 'keyword': + case 'naturalLanguage': + $this->job_tags[$attribute]['value'][] = $value; + break; + + case 'enum': + $value = $this->_enumBuild($attribute, $value); // may be overwritten by children + $this->job_tags[$attribute]['value'][] = $value; + break; + + case 'rangeOfInteger': + // $value have to be: INT1:INT2 , eg 100:1000 + $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value); + break; + + case 'resolution': + if (preg_match("#dpi#", $value)) { + $unit = chr(0x3); + } + if (preg_match("#dpc#", $value)) { + $unit = chr(0x4); + } + $search = array( + "#(dpi|dpc)#", + '#(x|-)#' + ); + $replace = array( + "", + ":" + ); + $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit; + $this->job_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + protected function _setOperationAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->operation_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'keyword': + case 'naturalLanguage': + $this->operation_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + protected function _setPrinterAttribute($attribute, $value) + { + //used by setAttribute + $tag_type = $this->printer_tags[$attribute]['tag']; + switch ($tag_type) + { + case 'integer': + $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value); + break; + + case 'keyword': + case 'naturalLanguage': + $this->printer_tags[$attribute]['value'][] = $value; + break; + + default: + trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE); + self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2); + return FALSE; + break; + } + $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag']; + } + + // + // DEBUGGING + // + protected function _putDebug($string, $level = 1) + { + if ($level === false) { + return; + } + + if ($level < $this->debug_level) { + return; + } + + $this->debug[$this->debug_count] = substr($string, 0, 1024); + $this->debug_count++; + //$this->debug .= substr($string,0,1024); + + } + + // + // LOGGING + // + protected function _errorLog($string_to_log, $level) + { + if ($level > $this->log_level) { + return; + } + + $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); + + if ($this->log_type == 0) + { + error_log($string); + return; + } + + $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log); + error_log($string, $this->log_type, $this->log_destination); + return; + } +} diff --git a/htdocs/includes/printipp/CupsPrintIPP.php b/htdocs/includes/printipp/CupsPrintIPP.php index a7e5a305da5..7808c64a722 100644 --- a/htdocs/includes/printipp/CupsPrintIPP.php +++ b/htdocs/includes/printipp/CupsPrintIPP.php @@ -1,5 +1,5 @@ jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - + for($i = 0 ; $i < count($attributes) ; $i++) + { if ($i == 0) + { $this->meta->attributes = chr(0x44) // Keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes[0]) . $attributes[0]; + } else + { $this->meta->attributes .= chr(0x44) // Keyword . chr(0x0).chr(0x0) // zero-length name . self::_giveMeStringLength($attributes[$i]) . $attributes[$i]; - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + } + } + + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x01) // operation: cups vendor extension: get defaults . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -97,69 +103,83 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $this->meta->language . $this->meta->attributes . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/')) { - + + if (self::_sendHttp ($post_values,'/')) + { + if(self::_parseServerOutput()) + { self::_parsePrinterAttributes(); } - + } + $this->attributes = &$this->printer_attributes; - - if (isset($this->printer_attributes->printer_type)) { + + if (isset($this->printer_attributes->printer_type)) + { $printer_type = $this->printer_attributes->printer_type->_value0; $table = self::_interpretPrinterType($printer_type); - - for($i = 0 ; $i < count($table) ; $i++ ) { + + for($i = 0 ; $i < count($table) ; $i++ ) + { $index = '_value'.$i; $this->printer_attributes->printer_type->$index = $table[$i]; } - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - - // {{{ cupsAcceptJobs ($printer_uri) - public function cupsAcceptJobs($printer_uri) { + + + public function cupsAcceptJobs($printer_uri) + { //The CUPS-Get-Default operation returns the default printer URI and attributes - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x08) // operation: cups vendor extension: Accept-Jobs . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -171,65 +191,80 @@ class CupsPrintIPP extends ExtendedPrintIPP { . self::_giveMeStringLength($printer_uri) . $printer_uri . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/admin/')) { - + + if (self::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false) - public function cupsRejectJobs($printer_uri,$printer_state_message) { + + public function cupsRejectJobs($printer_uri,$printer_state_message) + { //The CUPS-Get-Default operation returns the default printer URI and attributes - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); $this->parsed = array(); unset($this->attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - + $message = ""; if ($printer_state_message) + { $message = chr(0x04) // start printer-attributes . chr(0x41) // textWithoutLanguage . self::_giveMeStringLength("printer-state-message") . "printer-state-message" . self::_giveMeStringLength($printer_state_message) . $printer_state_message; + } - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x09) // operation: cups vendor extension: Reject-Jobs . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -242,89 +277,111 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $printer_uri . $message . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + self::_putDebug("Request: ".$this->output); - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/admin/')) { - + + if (self::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting defaults: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting defaults: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - - } else { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ getPrinters() - public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) { - + + public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) + { if (count($attributes) == 0) - true; - $attributes=array('printer-uri-supported','printer-location','printer-info','printer-type','color-supported'); + { + true; + } + $attributes=array('printer-uri-supported', 'printer-location', 'printer-info', 'printer-type', 'color-supported', 'printer-name'); $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + unset ($this->printers_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en-us'); - + } + self::_setOperationId(); - + $this->meta->attributes=''; - + if ($printer_location) + { $this->meta->attributes .= chr(0x41) // textWithoutLanguage . self::_giveMeStringLength('printer-location') . 'printer-location' . self::_giveMeStringLength($printer_location) . $printer_location; - - + } + if ($printer_info) + { $this->meta->attributes .= chr(0x41) // textWithoutLanguage . self::_giveMeStringLength('printer-info') . 'printer-info' . self::_giveMeStringLength($printer_info) . $printer_info; - + } + for($i = 0 ; $i < count($attributes) ; $i++) + { if ($i == 0) + { $this->meta->attributes .= chr(0x44) // Keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes[0]) . $attributes[0]; + } else + { $this->meta->attributes .= chr(0x44) // Keyword . chr(0x0).chr(0x0) // zero-length name . self::_giveMeStringLength($attributes[$i]) . $attributes[$i]; + } + } - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 . chr(0x40). chr(0x02) // operation: cups vendor extension: get printers . $this->meta->operation_id // request-id . chr(0x01) // start operation-attributes | operation-attributes-tag @@ -332,78 +389,89 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $this->meta->language . $this->meta->attributes . chr(0x03); // end operations attribute - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,'/')) { - - if(self::_parseServerOutput()) - $this->_getAvailablePrinters(); + if (self::_sendHttp ($post_values,'/')) + { + + if(self::_parseServerOutput()) + { + $this->_getAvailablePrinters(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { + $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("getting printers: ".$this->serveroutput->status,3); + } else + { self::_errorLog("getting printers: ".$this->serveroutput->status,1); - return $this->serveroutput->status; - - } else { + } + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting printers : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ cupsGetPrinters () - public function cupsGetPrinters () { - // alias for getPrinters(); + + public function cupsGetPrinters () + { + // alias for getPrinters(); self::getPrinters(); } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - // complete informations from parent with Cups-specific stuff - + + public function getPrinterAttributes() + { + // complete informations from parent with Cups-specific stuff + if(!$result = parent::getPrinterAttributes()) + { return FALSE; + } if(!isset($this->printer_attributes)) + { return FALSE; - - if (isset ($this->printer_attributes->printer_type)) { + } + + if (isset ($this->printer_attributes->printer_type)) + { $printer_type = $this->printer_attributes->printer_type->_value0; $table = self::_interpretPrinterType($printer_type); - - for($i = 0 ; $i < count($table) ; $i++ ) { + + for($i = 0 ; $i < count($table) ; $i++ ) + { $index = '_value'.$i; $this->printer_attributes->printer_type->$index = $table[$i]; - } } + } - return $result; + return $result; } - // }}} // // SETUP // - - // {{{ _initTags () - protected function _initTags () { - + protected function _initTags () + { // override parent with specific cups attributes - - $operation_tags = array (); + + $operation_tags = array (); $this->operation_tags = array_merge ($this->operation_tags, $operation_tags); - + $job_tags = array ( "job-billing" => array("tag" => "textWithoutLanguage"), "blackplot" => array("tag" => "boolean"), "brightness" => array("tag" => "integer"), @@ -430,25 +498,23 @@ class CupsPrintIPP extends ExtendedPrintIPP { "saturation" => array("tag" => "integer"), "scaling" => array("tag" => "integer"), "wrap" => array("tag","boolean"), - + ); $this->job_tags = array_merge ($this->job_tags, $job_tags); } - // }}} -// -// REQUEST BUILDING -// - - // {{{ _enumBuild ($tag,$value) - protected function _enumBuild ($tag,$value) { - + // + // REQUEST BUILDING + // + protected function _enumBuild ($tag,$value) + { $value_built = parent::_enumBuild($tag,$value); - - switch ($tag) { - case "cpi": - switch ($value) { + switch ($tag) + { + case "cpi": + switch ($value) + { case '10': $value_built = chr(10); break; @@ -463,7 +529,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { } break; case "lpi": - switch ($value) { + switch ($value) + { case '6': $value_built = chr(6); break; @@ -479,60 +546,66 @@ class CupsPrintIPP extends ExtendedPrintIPP { $prepend = ''; while ((strlen($value_built) + strlen($prepend)) < 4) $prepend .= chr(0); - return $prepend.$value_built; + return $prepend.$value_built; } - // }}} - -// -// RESPONSE PARSING -// - // {{{ _getAvailablePrinters () - private function _getAvailablePrinters () { - + // + // RESPONSE PARSING + // + private function _getAvailablePrinters () + { $this->available_printers = array(); + $this->printer_map = array(); $k = 0; - $this->printers_attributes = new stdClass(); + $this->printers_attributes = new \stdClass(); for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++) - if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") { + { + if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") + { $phpname = "_printer".$k; - $this->printers_attributes->$phpname = new stdClass(); - for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) { - + $this->printers_attributes->$phpname = new \stdClass(); + for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) + { + $value = $this->serveroutput->response[$i][$j]['value']; $name = str_replace("-","_",$this->serveroutput->response[$i][$j]['name']); - - switch ($name) { + + switch ($name) + { case "printer_uri_supported": $this->available_printers = array_merge($this->available_printers,array($value)); break; case "printer_type": $table = self::_interpretPrinterType($value); - $this->printers_attributes->$phpname->$name = new stdClass(); - - for($l = 0 ; $l < count($table) ; $l++ ) { + $this->printers_attributes->$phpname->$name = new \stdClass(); + + for($l = 0 ; $l < count($table) ; $l++ ) + { $index = '_value'.$l; $this->printers_attributes->$phpname->$name->$index = $table[$l]; } - + break; case '': break; + case 'printer_name': + $this->printer_map[$value] = $k; + break; default: $this->printers_attributes->$phpname->$name = $value; break; - } - - } - $k ++; + } } + $k ++; + } + } } - // }}} - - // {{{ _getEnumVendorExtensions - protected function _getEnumVendorExtensions ($value_parsed) { - switch ($value_parsed) { + + protected function _getEnumVendorExtensions ($value_parsed) + { + switch ($value_parsed) + { case 0x4002: $value = 'Get-Availables-Printers'; break; @@ -541,110 +614,152 @@ class CupsPrintIPP extends ExtendedPrintIPP { break; } - if (isset($value)) - return ($value); - - return sprintf('Unknown: 0x%x',$value_parsed); - } - // }}} + if (isset($value)) + { + return ($value); + } - // {{{ _interpretPrinterType($type) - private function _interpretPrinterType($value) { + return sprintf('Unknown: 0x%x',$value_parsed); + } + + + private function _interpretPrinterType($value) + { $value_parsed = 0; for ($i = strlen($value) ; $i > 0 ; $i --) + { $value_parsed += pow(256,($i - 1)) * ord($value[strlen($value) - $i]); - + } + $type[0] = $type[1] = $type[2] = $type[3] = $type[4] = $type[5] = ''; $type[6] = $type[7] = $type[8] = $type[9] = $type[10] = ''; $type[11] = $type[12] = $type[13] = $type[14] = $type[15] = ''; $type[16] = $type[17] = $type[18] = $type[19] = ''; - - if ($value_parsed %2 == 1) { + + if ($value_parsed %2 == 1) + { $type[0] = 'printer-class'; $value_parsed -= 1; - } - if ($value_parsed %4 == 2 ) { + } + + if ($value_parsed %4 == 2 ) + { $type[1] = 'remote-destination'; $value_parsed -= 2; - } - if ($value_parsed %8 == 4 ) { + } + + if ($value_parsed %8 == 4 ) + { $type[2] = 'print-black'; $value_parsed -= 4; - } - if ($value_parsed %16 == 8 ) { + } + + if ($value_parsed %16 == 8 ) + { $type[3] = 'print-color'; $value_parsed -= 8; - } - if ($value_parsed %32 == 16) { + } + + if ($value_parsed %32 == 16) + { $type[4] = 'hardware-print-on-both-sides'; $value_parsed -= 16; - } - if ($value_parsed %64 == 32) { + } + + if ($value_parsed %64 == 32) + { $type[5] = 'hardware-staple-output'; $value_parsed -= 32; - } - if ($value_parsed %128 == 64) { + } + + if ($value_parsed %128 == 64) + { $type[6] = 'hardware-fast-copies'; $value_parsed -= 64; - } - if ($value_parsed %256 == 128) { + } + + if ($value_parsed %256 == 128) + { $type[7] = 'hardware-fast-copy-collation'; $value_parsed -= 128; - } - if ($value_parsed %512 == 256) { + } + + if ($value_parsed %512 == 256) + { $type[8] = 'punch-output'; $value_parsed -= 256; - } - if ($value_parsed %1024 == 512) { + } + + if ($value_parsed %1024 == 512) + { $type[9] = 'cover-output'; $value_parsed -= 512; - } - if ($value_parsed %2048 == 1024) { + } + + if ($value_parsed %2048 == 1024) + { $type[10] = 'bind-output'; $value_parsed -= 1024; - } - if ($value_parsed %4096 == 2048) { + } + + if ($value_parsed %4096 == 2048) + { $type[11] = 'sort-output'; $value_parsed -= 2048; - } - if ($value_parsed %8192 == 4096) { + } + + if ($value_parsed %8192 == 4096) + { $type[12] = 'handle-media-up-to-US-Legal-A4'; $value_parsed -= 4096; - } - if ($value_parsed %16384 == 8192) { + } + + if ($value_parsed %16384 == 8192) + { $type[13] = 'handle-media-between-US-Legal-A4-and-ISO_C-A2'; $value_parsed -= 8192; - } - if ($value_parsed %32768 == 16384) { + } + + if ($value_parsed %32768 == 16384) + { $type[14] = 'handle-media-larger-than-ISO_C-A2'; $value_parsed -= 16384; - } - if ($value_parsed %65536 == 32768) { + } + + if ($value_parsed %65536 == 32768) + { $type[15] = 'handle-user-defined-media-sizes'; $value_parsed -= 32768; - } - if ($value_parsed %131072 == 65536) { + } + + if ($value_parsed %131072 == 65536) + { $type[16] = 'implicit-server-generated-class'; $value_parsed -= 65536; - } - if ($value_parsed %262144 == 131072) { + } + + if ($value_parsed %262144 == 131072) + { $type[17] = 'network-default-printer'; $value_parsed -= 131072; - } - if ($value_parsed %524288 == 262144) { + } + + if ($value_parsed %524288 == 262144) + { $type[18] = 'fax-device'; $value_parsed -= 262144; - } - return $type; - } - // }}} + } - // {{{ _interpretEnum() - protected function _interpretEnum($attribute_name,$value) { - + return $type; + } + + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'cpi': case 'lpi': $value = $value_parsed; @@ -652,20 +767,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { default: $value = parent::_interpretEnum($attribute_name,$value); break; - } - - - return $value; - } - // }}} - -}; + } -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> + return $value; + } +} \ No newline at end of file diff --git a/htdocs/includes/printipp/ExtendedPrintIPP.php b/htdocs/includes/printipp/ExtendedPrintIPP.php index e736f4bd972..3effacb828f 100644 --- a/htdocs/includes/printipp/ExtendedPrintIPP.php +++ b/htdocs/includes/printipp/ExtendedPrintIPP.php @@ -1,5 +1,5 @@ document_uri = $uri; $this->setup->uri = 1; } - + if(!$this->_stringUri()) + { return FALSE; - + } + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_parseJobAttributes(); $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); } } - + $this->attributes = &$this->job_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("printing uri %s, job %s: ",$uri,$this->last_job) .$this->serveroutput->status,3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("printing uri %s: ",$uri,$this->last_job) .$this->serveroutput->status,1); - } - return $this->serveroutput->status; } - + return $this->serveroutput->status; + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("printing uri $uri : OPERATION FAILED",1); - - return false; - } - // }}} - // {{{ purgeJobs() - public function purgeJobs() { - + return false; + } + + + public function purgeJobs() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("purgeJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("purgeJobs: Printer URI is not set: die\n")); self::_errorLog("purgeJobs: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x12) // purge-Jobs | operation-id . $this->meta->operation_id // request-id @@ -164,116 +169,141 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength(chr(0x01)) . chr(0x01) . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("purging jobs of %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("purging jobs of %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; + + return false; } - // }}} - - // {{{ createJob() - public function createJob() { - - + public function createJob() + { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("createJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("createJob: Printer URI is not set: die\n")); self::_errorLog("createJob: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->setup->copies)) + { self::setCopies(1); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->timeout)) + { $this->timeout = 60; - + } + $timeout = self::_integerBuild($this->timeout); - $this->meta->timeout = chr(0x21) // integer . self::_giveMeStringLength("multiple-operation-time-out") . "multiple-operation-time-out" . self::_giveMeStringLength($timeout) . $timeout; - + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x05) // Create-Job | operation-id . $this->meta->operation_id // request-id @@ -292,40 +322,44 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + unset ($this->meta->copies,$this->meta->sides,$this->meta->page_ranges); self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("creating job %s, printer %s\n"),$this->last_job,$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['printers'])) - if(self::_parseServerOutput()) { + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); - } + } + } - - - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("Create job: job %s"),$this->last_job) .$this->serveroutput->status,3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -333,186 +367,207 @@ class ExtendedPrintIPP extends PrintIPP { } return $this->serveroutput->status; } - + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("Creating job on %s : OPERATION FAILED"), $this->printer_uri),3); - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - return false; + return false; } - // }}} - - // {{{ sendDocument($job) - public function sendDocument($job,$is_last=false){ - + public function sendDocument($job,$is_last=false) + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); if (!$this->_stringDocument($job,$is_last)) + { return FALSE; - - if (is_readable($this->data)){ + } + + if (is_readable($this->data)) + { self::_putDebug( _("sending Document\n")); - + $this->output = $this->stringjob; - + if ($this->setup->datatype == "TEXT") - $this->output .= chr(0x16); // ASCII "SYN" - - + { + $this->output .= chr(0x16); + } // ASCII "SYN" + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output, "File" => $this->data); - + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { $post_values = array_merge($post_values,array("Filetype"=>"TEXT")); - - } else { + } + } + else + { self::_putDebug( _("sending DATA as document\n")); - + $this->output = $this->stringjob; $this->output .= $this->datahead; $this->output .= $this->data; $this->output .= $this->datatail; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - } - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); } - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),1); - } - return $this->serveroutput->status; - } + return $this->serveroutput->status; + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); self::_errorLog(sprintf("sending document, job %s : OPERATION FAILED",$job),1); - - return false; + + return false; } - // }}} - // {{{ sendURI ($uri,$job,$is_last=false) - public function sendURI ($uri,$job,$is_last=false){ + public function sendURI ($uri,$job,$is_last=false) + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); if (!$this->_stringSendUri($uri,$job,$is_last)) + { return FALSE; - + } + self::_putDebug( _("sending URI $uri\n")); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); } - } - + $this->attributes = &$this->job_attributes; - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf("sending uri %s, job %s: %s",$uri,$job,$this->serveroutput->status),3); - else { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog(sprintf("sending uri, job %s: %s",$uri,$job,$this->serveroutput->status),1); - } - return $this->serveroutput->status; - } + return $this->serveroutput->status; + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array($job)); $this->jobs_uri = array_merge($this->jobs_uri,array($job)); self::_errorLog(sprintf("sending uri %s, job %s : OPERATION FAILED",$uri,$job),1); - - return false; - } - // }}} - // {{{ pausePrinter () - public function pausePrinter() { - + return false; + } + + + public function pausePrinter() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("pausePrinter: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("pausePrinter: Printer URI is not set: die\n")); self::_errorLog("pausePrinter: Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x10) // Pause-Printer | operation-id . $this->meta->operation_id // request-id @@ -527,81 +582,94 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength(chr(0x01)) . chr(0x01) */ . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("pause printer %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("Pause printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("pause printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("pause printer %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; - } - // }}} - // {{{ resumePrinter () - public function resumePrinter() { - + return false; + } + + + public function resumePrinter() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("resumePrinter: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("resumePrinter: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x11) // suse-Printer | operation-id . $this->meta->operation_id // request-id @@ -611,82 +679,97 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->printer_uri . $this->meta->username . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("resume printer %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['admin'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("resume printer %s : OPERATION FAILED"), $this->printer_uri),3); - - return false; - } - // }}} - // {{{ holdJob ($job_uri) - public function holdJob ($job_uri,$until='indefinite') { - + return false; + } + + + public function holdJob ($job_uri,$until='indefinite') + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); $until_strings = array('no-hold','day-time','evening','night','weekend','second-shift','third-shift'); if (in_array($until,$until_strings)) + { true; + } else + { $until = 'indefinite'; + } $this->meta->job_hold_until = chr(0x42) // keyword . self::_giveMeStringLength('job-hold-until') . 'job-hold-until' . self::_giveMeStringLength($until) . $until; - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0C) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -698,68 +781,81 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->message . $this->meta->job_hold_until . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("hold job %s until %s\n"),$job_uri,$until)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("hold job %s until %s : OPERATION FAILED"), $job_uri,$until),3); - - return false; + + return false; } - // }}} - - // {{{ releaseJob ($job_uri) - public function releaseJob ($job_uri) { + + public function releaseJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0D) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -770,75 +866,85 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->username . $this->meta->message . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("release job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ restartJob ($job_uri) - public function restartJob ($job_uri) { - + + + public function restartJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setJobUri($job_uri); - - + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0E) // Hold-Job | operation-id . $this->meta->operation_id // request-id @@ -850,92 +956,110 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->message . $jobattributes // job-hold-until is set by setAttribute($attribute,$value) . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("release job %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("release job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ setJobAttributes ($job_uri,$deleted_attributes=array()) - public function setJobAttributes ($job_uri,$deleted_attributes=array()) { - + + + public function setJobAttributes ($job_uri,$deleted_attributes=array()) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri))); self::_setOperationId(); $this->parsed = array(); unset ($this->attributes); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - - if (!isset($this->meta->message)) - $this->meta->message = ''; + } + + if (!isset($this->meta->message)) + { + $this->meta->message = ''; + } - if (!isset($this->meta->copies)) + { $this->meta->copies = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; + } self::_setJobUri($job_uri); - + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + $this->meta->deleted_attributes = ""; for ($i = 0 ; $i < count($deleted_attributes) ; $i++) - $this->meta->deleted_attributes .= chr(0x16) // out-of-band value - . self::_giveMeStringLength($deleted_attributes[$i]) - . $deleted_attributes[$i] - . chr(0x0).chr(0x0); // value-length = 0; - - + { + $this->meta->deleted_attributes .= chr(0x16) // out-of-band value + . self::_giveMeStringLength($deleted_attributes[$i]) + . $deleted_attributes[$i] + . chr(0x0).chr(0x0); + } // value-length = 0; + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x14) // Set-Job-Attributes | operation-id . $this->meta->operation_id // request-id @@ -952,47 +1076,52 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $this->meta->deleted_attributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("set job attributes for job %s\n"),$job_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['jobs'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri) .$this->serveroutput->status,1); + } $this->last_job = $job_uri; $this->jobs_uri[count($this->jobs_uri) - 1] = $job_uri; return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("set job attributes for job %s: OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ setPrinterAttributes () - public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) { + + + public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) + { /* $document_format (RFC 3380) If the client includes this attribute, the Printer MUST change the supplied attributes for the document format specified by @@ -1010,55 +1139,72 @@ class ExtendedPrintIPP extends PrintIPP { supplied attributes for all document formats, whether or not they vary by document-format. */ - + $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); unset ($this->attributes); - + self::_setOperationId(); $this->parsed = array(); - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + if (!isset($this->meta->message)) + { $this->meta->message = ''; - + } + if (!isset($this->meta->copies)) + { $this->meta->copies = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + if ($document_format) + { $document_format = chr(0x49) // document-format tag - . self::_giveMeStringLength('document-format') - . 'document-format' // - . self::_giveMeStringLength($document_format) - . $document_format; // value + . self::_giveMeStringLength('document-format') + . 'document-format' // + . self::_giveMeStringLength($document_format) + . $document_format; + } // value $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + $this->meta->deleted_attributes = ""; for ($i = 0 ; $i < count($deleted_attributes) ; $i++) + { $this->meta->deleted_attributes .= chr(0x16) // out-of-band "deleted" value . self::_giveMeStringLength($deleted_attributes[$i]) . $deleted_attributes[$i] - . chr(0x0).chr(0x0); // value-length = 0; - - + . chr(0x0).chr(0x0); + } // value-length = 0; + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x13) // Set-Printer-Attributes | operation-id . $this->meta->operation_id // request-id @@ -1076,144 +1222,176 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $this->meta->deleted_attributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("set printer attributes for job %s\n"),$this->printer_uri)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("set printer attributes for printer %s: OPERATION FAILED"), $this->printer_uri),1); - - return false; - + + return false; } - // }}} -// REQUEST BUILDING - - // {{{ _setDocumentUri ($job_uri) - protected function _setDocumentUri () { - + // REQUEST BUILDING + protected function _setDocumentUri () + { $this->meta->document_uri = chr(0x45) // type uri . chr(0x00).chr(0x0c) // name-length . "document-uri" . self::_giveMeStringLength($this->document_uri) . $this->document_uri; - + self::_putDebug( "document uri is: ".$this->document_uri."\n"); $this->setup->document_uri = 1; - } - // }}} - // {{{ _stringUri () - protected function _stringUri () { - + + protected function _stringUri () + { self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + if (!isset($this->setup->document_uri)) + { trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Document URI is not set: die\n")); self::_errorLog("Document URI is not set, die",2); return FALSE; } unset ($this->setup->document_uri); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Printer URI is not set: die\n")); self::_errorLog("_stringUri: Printer URI is not set, die",2); return FALSE; - } } + } if (!isset($this->setup->charset)) + { $this->meta->charset = ""; - // self::setCharset('us-ascii'); + } if (!isset($this->setup->datatype)) + { self::setBinary(); - if (!isset($this->setup->uri)) { + } + if (!isset($this->setup->uri)) + { trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Printer URI is not set: die\n")); self::_errorLog("Printer URI is not set, die",2); return FALSE; - } + } if (!isset($this->setup->copies)) + { self::setCopies(1); - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { self::setMimeMediaType(); + } unset ($this->setup->mime_media_type); - + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->meta->username)) + { self::setUserName(); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - + if (!isset($this->error_generation->request_body_malformed)) + { $this->error_generation->request_body_malformed = ""; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x03) // Print-URI | operation-id . $this->meta->operation_id // request-id @@ -1234,72 +1412,98 @@ class ExtendedPrintIPP extends PrintIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - - // {{{ _stringDocument ($job,$is_last) - protected function _stringDocument ($job,$is_last) { - - if ($is_last == false) - $is_last = chr(0x00); - else - $is_last = chr(0x01); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + + protected function _stringDocument ($job,$is_last) + { + if ($is_last == false) + { + $is_last = chr(0x00); + } + else + { + $is_last = chr(0x01); + } + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->copies)) + { $this->meta->copies = ""; - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { $this->meta->mime_media_type = ""; + } if ($this->setup->datatype != "TEXT") + { unset ($this->setup->mime_media_type); - + } + if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x06) // Send-Document | operation-id . $this->meta->operation_id // request-id @@ -1322,84 +1526,107 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength($is_last) . $is_last . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - // {{{ _stringSendUri ($uri,$job,$is_last) - protected function _stringSendUri ($uri,$job,$is_last) { - + + protected function _stringSendUri ($uri,$job,$is_last) + { $this->document_uri = $uri; self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + if (!isset($this->setup->document_uri)) + { trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringUri: Document URI is not set: die\n")); self::_errorLog("Document URI is not set, die",2); return FALSE; } unset ($this->setup->document_uri); - - - if ($is_last == false) - $is_last = chr(0x00); - else - $is_last = chr(0x01); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + if ($is_last == false) + { + $is_last = chr(0x00); + } + else + { + $is_last = chr(0x01); + } + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n")); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->copies)) + { $this->meta->copies = ""; - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { $this->meta->mime_media_type = ""; + } unset ($this->setup->mime_media_type); - + if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $operationattributes = ''; $jobattributes = ''; $printerattributes = ''; self::_buildValues($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); - $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x07) // Send-Uri | operation-id . $this->meta->operation_id // request-id @@ -1422,20 +1649,8 @@ class ExtendedPrintIPP extends PrintIPP { . self::_giveMeStringLength($is_last) . $is_last . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - -}; - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> +} \ No newline at end of file diff --git a/htdocs/includes/printipp/PrintIPP.php b/htdocs/includes/printipp/PrintIPP.php index 9ed502c2d11..ffda9e8f1f7 100644 --- a/htdocs/includes/printipp/PrintIPP.php +++ b/htdocs/includes/printipp/PrintIPP.php @@ -1,5 +1,5 @@ _stringJob()) + { return FALSE; - - if (is_readable($this->data)){ + } + + if (is_readable($this->data)) + { self::_putDebug( _("Printing a FILE\n"),3); - + $this->output = $this->stringjob; - + if ($this->setup->datatype == "TEXT") + { $this->output .= chr(0x16); - - + } + $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output, "File" => $this->data); - + if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed)) + { $post_values = array_merge($post_values,array("Filetype"=>"TEXT")); - - } else { + } + } + else + { self::_putDebug( _("Printing DATA\n"),3); - + $this->output = $this->stringjob; $this->output .= $this->datahead; $this->output .= $this->data; @@ -99,25 +90,25 @@ class PrintIPP extends BasicIPP { $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - } - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + else + { $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); } - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") @@ -131,138 +122,174 @@ class PrintIPP extends BasicIPP { self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1); if ($this->with_exceptions) { - throw new ippException(sprintf("job status: %s", + throw new ippException(sprintf("job status: %s", $this->serveroutput->status)); } } return $this->serveroutput->status; - - } + } $this->status = array_merge($this->status,array("OPERATION FAILED")); $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_errorLog("printing job : OPERATION FAILED",1); - - return false; - } - // }}} - // {{{ cancelJob ($job_uri) - public function cancelJob ($job_uri) { - + return false; + } + + public function cancelJob ($job_uri) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); - + if (!$this->_stringCancel($job_uri)) - return FALSE; - + { + return FALSE; + } + self::_putDebug( _("Cancelling Job $job_uri\n"),3); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,3); - else - self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1); - return $this->serveroutput->status; - } + else + { + self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1); + } + return $this->serveroutput->status; + } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("cancelling job : OPERATION FAILED",3); - - return false; + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog("cancelling job : OPERATION FAILED",3); + + return false; } - // }}} - // {{{ validateJob () - public function validateJob () { - + public function validateJob () + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - + $this->serveroutput->response = ''; self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); - - - self::_putDebug( _("Validate Job\n"),2); - - if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - if (!isset($this->setup->datatype)) - self::setBinary(); - if (!isset($this->setup->uri)) { + self::_putDebug( _("Validate Job\n"),2); + + if (!isset($this->setup->charset)) + { + self::setCharset(); + } + if (!isset($this->setup->datatype)) + { + self::setBinary(); + } + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->meta->copies)) + { self::setCopies(1); + } + if (!isset($this->setup->copies)) + { self::setCopies(1); - + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->setup->mime_media_type)) + { self::setMimeMediaType(); + } + if ($this->setup->datatype != "TEXT") - unset ($this->setup->mime_media_type); - + { + unset ($this->setup->mime_media_type); + } + if (!isset($this->setup->jobname)) + { if (is_readable($this->data)) + { self::setJobName(basename($this->data),true); + } else + { self::setJobName(); + } + } unset($this->setup->jobname); if (!isset($this->meta->username)) + { self::setUserName(); + } if (!isset($this->meta->fidelity)) + { $this->meta->fidelity = ''; - + } + if (!isset($this->meta->document_name)) + { $this->meta->document_name = ''; + } if (!isset($this->meta->sides)) + { $this->meta->sides = ''; - + } + if (!isset($this->meta->page_ranges)) + { $this->meta->page_ranges = ''; - + } + $jobattributes = ''; $operationattributes = ''; $printerattributes = ''; self::_buildValues ($operationattributes,$jobattributes,$printerattributes); - + self::_setOperationId(); $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number @@ -284,43 +311,45 @@ class PrintIPP extends BasicIPP { . $this->meta->page_ranges . $jobattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['printers'])) - if(self::_parseServerOutput()) - self::_parseAttributes(); - - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + { + if(self::_parseServerOutput()) + { + self::_parseAttributes(); + } + } + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog("validate job: ".$this->serveroutput->status,3); - else - self::_errorLog("validate job: ".$this->serveroutput->status,1); - - return $this->serveroutput->status; - } + else + { + self::_errorLog("validate job: ".$this->serveroutput->status,1); + } + return $this->serveroutput->status; + } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("validate job : OPERATION FAILED",3); - - return false; + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog("validate job : OPERATION FAILED",3); + + return false; } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - + public function getPrinterAttributes() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -330,32 +359,42 @@ class PrintIPP extends BasicIPP { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog(" Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0b) // Print-URI | operation-id . $this->meta->operation_id // request-id @@ -366,109 +405,137 @@ class PrintIPP extends BasicIPP { . $this->meta->username . $printerattributes . chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("Getting printer attributes of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['root'])) + { if (self::_parseServerOutput()) + { self::_parsePrinterAttributes(); - + } + } + $this->attributes = &$this->printer_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri, $this->serveroutput->status),3); + } else + { self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri, $this->serveroutput->status),1); - - return $this->serveroutput->status; } - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog(date("Y-m-d H:i:s : ") - .basename($_SERVER['PHP_SELF']) - .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"), - $this->printer_uri),3); - - return false; - } - // }}} + return $this->serveroutput->status; + } - // {{{ getJobs ($my_jobs=true,$limit=0,$which_jobs=""); - public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) { - + $this->status = array_merge($this->status,array("OPERATION FAILED")); + self::_errorLog(date("Y-m-d H:i:s : ") + .basename($_SERVER['PHP_SELF']) + .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"), + $this->printer_uri),3); + + return false; + } + + public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog("getJobs: Printer URI is not set, die",2); return FALSE; } } - + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); + } - if ($limit) { + if ($limit) + { $limit = self::_integerBuild($limit); $this->meta->limit = chr(0x21) // integer . self::_giveMeStringLength('limit') . 'limit' . self::_giveMeStringLength($limit) . $limit; - } else + } + else + { $this->meta->limit = ''; - + } + if ($which_jobs == 'completed') + { $this->meta->which_jobs = chr(0x44) // keyword . self::_giveMeStringLength('which-jobs') . 'which-jobs' . self::_giveMeStringLength($which_jobs) . $which_jobs; + } else + { $this->meta->which_jobs = ""; + } if ($my_jobs) + { $this->meta->my_jobs = chr(0x22) // boolean . self::_giveMeStringLength('my-jobs') . 'my-jobs' . self::_giveMeStringLength(chr(0x01)) . chr(0x01); + } else + { $this->meta->my_jobs = ''; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x0A) // Get-Jobs | operation-id . $this->meta->operation_id // request-id @@ -479,9 +546,9 @@ class PrintIPP extends BasicIPP { . $this->meta->username . $this->meta->limit . $this->meta->which_jobs - . $this->meta->my_jobs - ; - if ($subset) { + . $this->meta->my_jobs; + if ($subset) + { $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') @@ -502,106 +569,122 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; + . 'job-state-reason'; } - else { # cups 1.4.4 doesn't return much of anything without this + else + { # cups 1.4.4 doesn't return much of anything without this $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength('all') - . 'all' - ; + . 'all'; } $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { if (self::_parseServerOutput()) + { self::_parseJobsAttributes(); - + } + } + $this->attributes = &$this->jobs_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("getting jobs of %s : OPERATION FAILED"), $this->printer_uri),3); - + return false; } - // }}} - // {{{ getJobAttributes ($job_uri,subset="false",$attributes_group="all"); - public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") { - + + public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); - - if (!$job_uri) { + + if (!$job_uri) + { trigger_error(_("getJobAttributes: Job URI is not set, die.")); return FALSE; } - + self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + if (!isset($this->setup->uri)) + { $this->getPrinters(); unset($this->jobs[count($this->jobs) - 1]); unset($this->jobs_uri[count($this->jobs_uri) - 1]); unset($this->status[count($this->status) - 1]); - + if (array_key_exists(0,$this->available_printers)) + { self::setPrinterURI($this->available_printers[0]); - else { + } + else + { trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING); self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3); self::_errorLog("getJobs: Printer URI is not set, die",2); return FALSE; - } } - + } + if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); + } $this->meta->job_uri = chr(0x45) // URI . self::_giveMeStringLength('job-uri') . 'job-uri' . self::_giveMeStringLength($job_uri) . $job_uri; - + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x09) // Get-Job-Attributes | operation-id . $this->meta->operation_id // request-id @@ -609,10 +692,10 @@ class PrintIPP extends BasicIPP { . $this->meta->charset . $this->meta->language . $this->meta->job_uri - . $this->meta->username - ; - if ($subset) - $this->stringjob .= + . $this->meta->username; + if ($subset) + { + $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' @@ -632,10 +715,12 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; - elseif($attributes_group) { - switch($attributes_group) { + . 'job-state-reason'; + } + elseif($attributes_group) + { + switch($attributes_group) + { case 'job-template': break; case 'job-description': @@ -646,127 +731,116 @@ class PrintIPP extends BasicIPP { trigger_error(_('not a valid attribute group: ').$attributes_group,E_USER_NOTICE); $attributes_group = ''; break; - } + } $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' . self::_giveMeStringLength($attributes_group) . $attributes_group; - } + } $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag - + self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); - + self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); - + $this->output = $this->stringjob; - + $post_values = array( "Content-Type"=>"application/ipp", "Data"=>$this->output); - + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { if (self::_parseServerOutput()) + { self::_parseJobAttributes(); - + } + } + $this->attributes = &$this->job_attributes; - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); - + if ($this->serveroutput->status == "successfull-ok") + { self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri) .$this->serveroutput->status,3); + } else + { self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri) .$this->serveroutput->status,1); - + } + return $this->serveroutput->status; - } - + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog(date("Y-m-d H:i:s : ") .basename($_SERVER['PHP_SELF']) .sprintf(_("getting jobs attributes of %s : OPERATION FAILED"), $job_uri),3); - - return false; + + return false; } - // }}} - - // {{{ getPrinters(); - public function getPrinters() { - + public function getPrinters() + { // placeholder for vendor extension operation (getAvailablePrinters for CUPS) $this->jobs = array_merge($this->jobs,array('')); $this->jobs_uri = array_merge($this->jobs_uri,array('')); $this->status = array_merge($this->status,array('')); } - // }}} -/****************** -* -* DEVELOPPEMENT FUNCTIONS -* -*******************/ - - // {{{ generateError($error) - public function generateError ($error) { - switch ($error) { + public function generateError ($error) + { + switch ($error) + { case "request_body_malformed": $this->error_generation->request_body_malformed = chr(0xFF); break; default: true; break; - } - // }}} + } - // {{{ resetError ($error) trigger_error(sprintf(_('Setting Error %s'),$error),E_USER_NOTICE); } - public function resetError ($error) { + public function resetError ($error) + { unset ($this->error_generation->$error); trigger_error(sprintf(_('Reset Error %s'),$error),E_USER_NOTICE); } - // }}} -/****************** -* -* PROTECTED FUNCTIONS -* -*******************/ - -// SETUP - - // {{{ _setOperationId () - protected function _setOperationId () { + // SETUP + protected function _setOperationId () + { $prepend = ''; $this->operation_id += 1; $this->meta->operation_id = self::_integerBuild($this->operation_id); self::_putDebug( "operation id is: ".$this->operation_id."\n",2); } - // }}} - // {{{ _setJobId() - protected function _setJobId() { + protected function _setJobId() + { $this->meta->jobid +=1; $prepend = ''; $prepend_length = 4 - strlen($this->meta->jobid); for ($i = 0; $i < $prepend_length ; $i++ ) + { $prepend .= '0'; + } return $prepend.$this->meta->jobid; } - // }}} - // {{{ _setJobUri ($job_uri) - protected function _setJobUri ($job_uri) { - + protected function _setJobUri ($job_uri) + { $this->meta->job_uri = chr(0x45) // type uri . chr(0x00).chr(0x07) // name-length . "job-uri" @@ -776,441 +850,490 @@ class PrintIPP extends BasicIPP { self::_putDebug( "job-uri is: ".$job_uri."\n",2); } - // }}} - -// RESPONSE PARSING - - // {{{ _parsePrinterAttributes() - protected function _parsePrinterAttributes() { + // RESPONSE PARSING + protected function _parsePrinterAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; } + } + } $this->serveroutput->response = array(); - - $this->printer_attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + + $this->printer_attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->printer_attributes->$php_name = new stdClass(); + $this->printer_attributes->$php_name = new \stdClass(); $this->printer_attributes->$php_name->_type = $type; $this->printer_attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->printer_attributes->$php_name->$index = $value; } } - + $this->parsed = array(); - - } - // }}} - - // {{{ _parseJobsAttributes() - protected function _parseJobsAttributes() { + protected function _parseJobsAttributes() + { //if ($this->serveroutput->status != "successfull-ok") // return false; - + $job = -1; - for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) { + $l = 0; + for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { if ($this->serveroutput->response[$i]['attributes'] == "job-attributes") + { $job ++; + } $k = -1; for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$job][$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$job][$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$job][$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } - } - - $this->serveroutput->response = array(); - $this->jobs_attributes = new stdClass(); - for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) { - $job_index = "job_".$job_nbr; - $this->jobs_attributes->$job_index = new stdClass(); - for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) { - $name = $this->parsed[$job_nbr][$i]['name']; - $php_name = str_replace('-','_',$name); - $type = $this->parsed[$job_nbr][$i]['type']; - $range = $this->parsed[$job_nbr][$i]['range']; - $this->jobs_attributes->$job_index->$php_name = new stdClass(); - $this->jobs_attributes->$job_index->$php_name->_type = $type; - $this->jobs_attributes->$job_index->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) { - # This causes incorrect parsing of integer job attributes. - # 2010-08-16 - # bpkroth - #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]); - $value = $this->parsed[$job_nbr][$i][$j]; - $index = '_value'.$j; - $this->jobs_attributes->$job_index->$php_name->$index = $value; - } - } - } - - $this->parsed = array(); - - - } - // }}} - - // {{{ _readAttribute($attributes_type,$ji,&$collection=false) - protected function _readAttribute($attributes_type) { - - $tag = ord($this->serveroutput->body[$this->_parsing->offset]); - - $this->_parsing->offset += 1; - $j = $this->index; - - $tag = self::_readTag($tag); - - switch ($tag) { - case "begCollection": //RFC3382 (BLIND CODE) - if ($this->end_collection) - $this->index --; - $this->end_collection = false; - $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; - self::_putDebug( "tag is: begCollection\n"); - self::_readAttributeName ($attributes_type,$j); - if (!$this->serveroutput->response[$attributes_type][$j]['name']) { // it is a multi-valued collection - $this->collection_depth ++; - $this->index --; - $this->collection_nbr[$this->collection_depth] ++; - } else { - $this->collection_depth ++; - if ($this->collection_depth == 0) - $this->collection = (object) 'collection'; - if (array_key_exists($this->collection_depth,$this->collection_nbr)) - $this->collection_nbr[$this->collection_depth] ++; - else - $this->collection_nbr[$this->collection_depth] = 0; - unset($this->end_collection); - - } - self::_readValue ("begCollection",$attributes_type,$j); - break; - case "endCollection": //RFC3382 (BLIND CODE) - $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; - self::_putDebug( "tag is: endCollection\n"); - self::_readAttributeName ($attributes_type,$j,0); - self::_readValue ('name',$attributes_type,$j,0); - $this->collection_depth --; - $this->collection_key[$this->collection_depth] = 0; - $this->end_collection = true; - break; - case "memberAttrName": // RFC3382 (BLIND CODE) - $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName"; - $this->index -- ; - self::_putDebug( "tag is: memberAttrName\n"); - self::_readCollection ($attributes_type,$j); - break; - - default: - $this->collection_depth = -1; - $this->collection_key = array(); - $this->collection_nbr = array(); - $this->serveroutput->response[$attributes_type][$j]['type'] = $tag; - self::_putDebug( "tag is: $tag\n"); - $attribute_name = self::_readAttributeName ($attributes_type,$j); - if (!$attribute_name) - $attribute_name = $this->attribute_name; - else - $this->attribute_name = $attribute_name; - $value = self::_readValue ($tag,$attributes_type,$j); - $this->serveroutput->response[$attributes_type][$j]['value'] = - self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']); - break; - - } - return; - } - // }}} - - // {{{ _readTag($tag) - protected function _readTag($tag) { - - switch ($tag) { - case 0x10: - $tag = "unsupported"; - break; - case 0x11: - $tag = "reserved for 'default'"; - break; - case 0x12: - $tag = "unknown"; - break; - case 0x13: - $tag = "no-value"; - break; - case 0x15: // RFC 3380 - $tag = "not-settable"; - break; - case 0x16: // RFC 3380 - $tag = "delete-attribute"; - break; - case 0x17: // RFC 3380 - $tag = "admin-define"; - break; - case 0x20: - $tag = "IETF reserved (generic integer)"; - break; - case 0x21: - $tag = "integer"; - break; - case 0x22: - $tag = "boolean"; - break; - case 0x23: - $tag = "enum"; - break; - case 0x30: - $tag = "octetString"; - break; - case 0x31: - $tag = "datetime"; - break; - case 0x32: - $tag = "resolution"; - break; - case 0x33: - $tag = "rangeOfInteger"; - break; - case 0x34: //RFC3382 (BLIND CODE) - $tag = "begCollection"; - break; - case 0x35: - $tag = "textWithLanguage"; - break; - case 0x36: - $tag = "nameWithLanguage"; - break; - case 0x37: //RFC3382 (BLIND CODE) - $tag = "endCollection"; - break; - case 0x40: - $tag = "IETF reserved text string"; - break; - case 0x41: - $tag = "textWithoutLanguage"; - break; - case 0x42: - $tag = "nameWithoutLanguage"; - break; - case 0x43: - $tag = "IETF reserved for future"; - break; - case 0x44: - $tag = "keyword"; - break; - case 0x45: - $tag = "uri"; - break; - case 0x46: - $tag = "uriScheme"; - break; - case 0x47: - $tag = "charset"; - break; - case 0x48: - $tag = "naturalLanguage"; - break; - case 0x49: - $tag = "mimeMediaType"; - break; - case 0x4A: // RFC3382 (BLIND CODE) - $tag = "memberAttrName"; - break; - case 0x7F: - $tag = "extended type"; - break; - default: - - if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) - $tag = "out-of-band"; - elseif (0x24 <= $tag && $tag <= 0x2f) - $tag = "new integer type"; - elseif (0x38 <= $tag && $tag <= 0x3F) - $tag = "new octet-stream type"; - elseif (0x4B <= $tag && $tag <= 0x5F) - $tag = "new character string type"; - elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 ) - $tag = "IETF reserved for future"; - else - $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag); - - break; } - return $tag; - } - // }}} + } + } - // {{{ _readCollection($attributes_type,$j,&$collection) - protected function _readCollection($attributes_type,$j) { - + $this->serveroutput->response = array(); + $this->jobs_attributes = new \stdClass(); + for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) + { + $job_index = "job_".$job_nbr; + $this->jobs_attributes->$job_index = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) + { + $name = $this->parsed[$job_nbr][$i]['name']; + $php_name = str_replace('-','_',$name); + $type = $this->parsed[$job_nbr][$i]['type']; + $range = $this->parsed[$job_nbr][$i]['range']; + $this->jobs_attributes->$job_index->$php_name = new \stdClass(); + $this->jobs_attributes->$job_index->$php_name->_type = $type; + $this->jobs_attributes->$job_index->$php_name->_range = $range; + for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) + { + # This causes incorrect parsing of integer job attributes. + # 2010-08-16 + # bpkroth + #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]); + $value = $this->parsed[$job_nbr][$i][$j]; + $index = '_value'.$j; + $this->jobs_attributes->$job_index->$php_name->$index = $value; + } + } + } + + $this->parsed = array(); + } + + protected function _readAttribute($attributes_type) + { + $tag = ord($this->serveroutput->body[$this->_parsing->offset]); + + $this->_parsing->offset += 1; + $j = $this->index; + + $tag = self::_readTag($tag); + + switch ($tag) + { + case "begCollection": //RFC3382 (BLIND CODE) + if ($this->end_collection) + { + $this->index --; + } + $this->end_collection = false; + $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; + self::_putDebug( "tag is: begCollection\n"); + self::_readAttributeName ($attributes_type,$j); + if (!$this->serveroutput->response[$attributes_type][$j]['name']) + { // it is a multi-valued collection + $this->collection_depth ++; + $this->index --; + $this->collection_nbr[$this->collection_depth] ++; + } + else + { + $this->collection_depth ++; + if ($this->collection_depth == 0) + { + $this->collection = (object) 'collection'; + } + if (array_key_exists($this->collection_depth,$this->collection_nbr)) + { + $this->collection_nbr[$this->collection_depth] ++; + } + else + { + $this->collection_nbr[$this->collection_depth] = 0; + } + unset($this->end_collection); + } + self::_readValue ("begCollection",$attributes_type,$j); + break; + case "endCollection": //RFC3382 (BLIND CODE) + $this->serveroutput->response[$attributes_type][$j]['type'] = "collection"; + self::_putDebug( "tag is: endCollection\n"); + self::_readAttributeName ($attributes_type,$j,0); + self::_readValue ('name',$attributes_type,$j,0); + $this->collection_depth --; + $this->collection_key[$this->collection_depth] = 0; + $this->end_collection = true; + break; + case "memberAttrName": // RFC3382 (BLIND CODE) + $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName"; + $this->index -- ; + self::_putDebug( "tag is: memberAttrName\n"); + self::_readCollection ($attributes_type,$j); + break; + + default: + $this->collection_depth = -1; + $this->collection_key = array(); + $this->collection_nbr = array(); + $this->serveroutput->response[$attributes_type][$j]['type'] = $tag; + self::_putDebug( "tag is: $tag\n"); + $attribute_name = self::_readAttributeName ($attributes_type,$j); + if (!$attribute_name) + { + $attribute_name = $this->attribute_name; + } + else + { + $this->attribute_name = $attribute_name; + } + $value = self::_readValue ($tag,$attributes_type,$j); + $this->serveroutput->response[$attributes_type][$j]['value'] = + self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']); + break; + } + return; + } + + protected function _readTag($tag) + { + switch ($tag) + { + case 0x10: + $tag = "unsupported"; + break; + case 0x11: + $tag = "reserved for 'default'"; + break; + case 0x12: + $tag = "unknown"; + break; + case 0x13: + $tag = "no-value"; + break; + case 0x15: // RFC 3380 + $tag = "not-settable"; + break; + case 0x16: // RFC 3380 + $tag = "delete-attribute"; + break; + case 0x17: // RFC 3380 + $tag = "admin-define"; + break; + case 0x20: + $tag = "IETF reserved (generic integer)"; + break; + case 0x21: + $tag = "integer"; + break; + case 0x22: + $tag = "boolean"; + break; + case 0x23: + $tag = "enum"; + break; + case 0x30: + $tag = "octetString"; + break; + case 0x31: + $tag = "datetime"; + break; + case 0x32: + $tag = "resolution"; + break; + case 0x33: + $tag = "rangeOfInteger"; + break; + case 0x34: //RFC3382 (BLIND CODE) + $tag = "begCollection"; + break; + case 0x35: + $tag = "textWithLanguage"; + break; + case 0x36: + $tag = "nameWithLanguage"; + break; + case 0x37: //RFC3382 (BLIND CODE) + $tag = "endCollection"; + break; + case 0x40: + $tag = "IETF reserved text string"; + break; + case 0x41: + $tag = "textWithoutLanguage"; + break; + case 0x42: + $tag = "nameWithoutLanguage"; + break; + case 0x43: + $tag = "IETF reserved for future"; + break; + case 0x44: + $tag = "keyword"; + break; + case 0x45: + $tag = "uri"; + break; + case 0x46: + $tag = "uriScheme"; + break; + case 0x47: + $tag = "charset"; + break; + case 0x48: + $tag = "naturalLanguage"; + break; + case 0x49: + $tag = "mimeMediaType"; + break; + case 0x4A: // RFC3382 (BLIND CODE) + $tag = "memberAttrName"; + break; + case 0x7F: + $tag = "extended type"; + break; + default: + if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) + { + $tag = "out-of-band"; + } + elseif (0x24 <= $tag && $tag <= 0x2f) + { + $tag = "new integer type"; + } + elseif (0x38 <= $tag && $tag <= 0x3F) + { + $tag = "new octet-stream type"; + } + elseif (0x4B <= $tag && $tag <= 0x5F) + { + $tag = "new character string type"; + } + elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 ) + { + $tag = "IETF reserved for future"; + } + else + { + $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag); + } + break; + } + + return $tag; + } + + protected function _readCollection($attributes_type,$j) + { $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - + $this->_parsing->offset += 2; - + self::_putDebug( "Collection name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $collection_name = $name; - + $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "Attribute name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $attribute_name = $name; - if ($attribute_name == "") { + if ($attribute_name == "") + { $attribute_name = $this->last_attribute_name; $this->collection_key[$this->collection_depth] ++; - } else { + } + else + { $this->collection_key[$this->collection_depth] = 0; } $this->last_attribute_name = $attribute_name; - + self::_putDebug( "Attribute name ".$name."\n"); - + $tag = self::_readTag(ord($this->serveroutput->body[$this->_parsing->offset])); $this->_parsing->offset ++; - + $type = $tag; - + $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "Collection2 name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; if ($this->_parsing->offset > strlen($this->serveroutput->body)) + { return; } - + } + $collection_value = $name; $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); - + self::_putDebug( "Collection value_length ".$this->serveroutput->body[ $this->_parsing->offset] . $this->serveroutput->body[$this->_parsing->offset + 1] .": " . $value_length . " "); - + $this->_parsing->offset += 2; - + $value = ''; - for ($i = 0; $i < $value_length; $i++) { - + for ($i = 0; $i < $value_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $value .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - - } - + } + $object = &$this->collection; - for ($i = 0 ; $i <= $this->collection_depth ; $i ++) { + for ($i = 0 ; $i <= $this->collection_depth ; $i ++) + { $indice = "_indice".$this->collection_nbr[$i]; if (!isset($object->$indice)) + { $object->$indice = (object) 'indice'; - $object = &$object->$indice; } - + $object = &$object->$indice; + } + $value_key = "_value".$this->collection_key[$this->collection_depth]; $col_name_key = "_collection_name".$this->collection_key[$this->collection_depth]; $col_val_key = "_collection_value".$this->collection_key[$this->collection_depth]; - + $attribute_value = self::_interpretAttribute($attribute_name,$tag,$value); $attribute_name = str_replace('-','_',$attribute_name); - - + self::_putDebug( sprintf("Value: %s\n",$value)); $object->$attribute_name->_type = $type; $object->$attribute_name->$value_key = $attribute_value; $object->$attribute_name->$col_name_key = $collection_name; $object->$attribute_name->$col_val_key = $collection_value; - - $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection; - } - // }}} - - // {{{ _readAttributeName ($attributes_type,$j) - protected function _readAttributeName ($attributes_type,$j,$write=1) { + $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection; + } + + protected function _readAttributeName ($attributes_type,$j,$write=1) + { $name_length = ord($this->serveroutput->body[ $this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); $this->_parsing->offset += 2; - + self::_putDebug( "name_length ". $name_length ."\n"); - + $name = ''; - for ($i = 0; $i < $name_length; $i++) { + for ($i = 0; $i < $name_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $name .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - } - + } + if($write) - $this->serveroutput->response[$attributes_type][$j]['name'] = $name; + { + $this->serveroutput->response[$attributes_type][$j]['name'] = $name; + } self::_putDebug( "name " . $name . "\n"); - - return $name; + + return $name; } - // }}} - - // {{{ _readValue ($type,$attributes_type,$j) - protected function _readValue ($type,$attributes_type,$j,$write=1) { + protected function _readValue ($type,$attributes_type,$j,$write=1) + { $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256 + ord($this->serveroutput->body[$this->_parsing->offset + 1]); @@ -1219,116 +1342,130 @@ class PrintIPP extends BasicIPP { .": " . $value_length . " "); - + $this->_parsing->offset += 2; - + $value = ''; - for ($i = 0; $i < $value_length; $i++) { - + for ($i = 0; $i < $value_length; $i++) + { if ($this->_parsing->offset >= strlen($this->serveroutput->body)) + { return; + } $value .= $this->serveroutput->body[$this->_parsing->offset]; $this->_parsing->offset += 1; - } - + self::_putDebug( sprintf("Value: %s\n",$value)); - + if ($write) - $this->serveroutput->response[$attributes_type][$j]['value'] = $value; + { + $this->serveroutput->response[$attributes_type][$j]['value'] = $value; + } - return $value; + return $value; } - // }}} - // {{{ _parseAttributes() - protected function _parseAttributes() { - + protected function _parseAttributes() + { $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } + } + } + } $this->serveroutput->response = array(); - $this->attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + $this->attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->attributes->$php_name = new stdClass(); + $this->attributes->$php_name = new \stdClass(); $this->attributes->$php_name->_type = $type; $this->attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->attributes->$php_name->$index = $value; } } - + $this->parsed = array(); - } - // }}} - - // {{{ _parseJobAttributes() - protected function _parseJobAttributes() { + protected function _parseJobAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; - $k = -1; + $l = 0; for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) + { for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++) - if (!empty($this->serveroutput->response[$i][$j]['name'])) { + { + if (!empty($this->serveroutput->response[$i][$j]['name'])) + { $k++; $l = 0; $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes']; $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name']; $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type']; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } else { + } + else + { $l ++; $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value']; - } - + } + } + } + $this->serveroutput->response = array(); - - $this->job_attributes = new stdClass(); - for ($i = 0 ; $i < count($this->parsed) ; $i ++) { + + $this->job_attributes = new \stdClass(); + for ($i = 0 ; $i < count($this->parsed) ; $i ++) + { $name = $this->parsed[$i]['name']; $php_name = str_replace('-','_',$name); $type = $this->parsed[$i]['type']; $range = $this->parsed[$i]['range']; - $this->job_attributes->$php_name = new stdClass(); + $this->job_attributes->$php_name = new \stdClass(); $this->job_attributes->$php_name->_type = $type; $this->job_attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) + { $value = $this->parsed[$i][$j]; $index = '_value'.$j; $this->job_attributes->$php_name->$index = $value; } } - - $this->parsed = array(); - - - } - // }}} - // {{{ _interpretAttribute($attribute_name,$type,$value) - protected function _interpretAttribute($attribute_name,$type,$value) { - - switch ($type) { + $this->parsed = array(); + } + + protected function _interpretAttribute($attribute_name,$type,$value) + { + switch ($type) + { case "integer": $value = self::_interpretInteger($value); break; @@ -1338,9 +1475,13 @@ class PrintIPP extends BasicIPP { case 'boolean': $value = ord($value); if ($value == 0x00) + { $value = 'false'; + } else + { $value = 'true'; + } break; case 'datetime': $value = self::_interpretDateTime($value); @@ -1351,7 +1492,8 @@ class PrintIPP extends BasicIPP { case 'resolution': $unit = $value[8]; $value = self::_interpretRangeOfInteger(substr($value,0,8)); - switch($unit) { + switch($unit) + { case chr(0x03): $unit = "dpi"; break; @@ -1363,31 +1505,27 @@ class PrintIPP extends BasicIPP { break; default: break; - } - return $value; + } + return $value; } - // }}} - - // {{{ _interpretRangeOfInteger($value) - protected function _interpretRangeOfInteger($value) { - + + protected function _interpretRangeOfInteger($value) + { $value_parsed = 0; $integer1 = $integer2 = 0; - + $halfsize = strlen($value) / 2; - + $integer1 = self::_interpretInteger(substr($value,0,$halfsize)); $integer2 = self::_interpretInteger(substr($value,$halfsize,$halfsize)); - + $value_parsed = sprintf('%s-%s',$integer1,$integer2); - - - return $value_parsed; + + return $value_parsed; } - // }}} - - // {{{ _interpretDateTime($date) { - protected function _interpretDateTime($date) { + + protected function _interpretDateTime($date) + { $year = self::_interpretInteger(substr($date,0,2)); $month = self::_interpretInteger(substr($date,2,1)); $day = self::_interpretInteger(substr($date,3,1)); @@ -1397,21 +1535,21 @@ class PrintIPP extends BasicIPP { $direction = substr($date,8,1); $hours_from_utc = self::_interpretInteger(substr($date,9,1)); $minutes_from_utc = self::_interpretInteger(substr($date,10,1)); - + $date = sprintf('%s-%s-%s %s:%s:%s %s%s:%s',$year,$month,$day,$hour,$minute,$second,$direction,$hours_from_utc,$minutes_from_utc); - return $date; - } - // }}} - - // {{{ _interpretEnum() - protected function _interpretEnum($attribute_name,$value) { - + return $date; + } + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'job-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'pending'; break; @@ -1433,14 +1571,17 @@ class PrintIPP extends BasicIPP { case 0x09: $value = 'completed'; break; - } + } if ($value_parsed > 0x09) + { $value = sprintf('Unknown(IETF standards track "job-state" reserved): 0x%x',$value_parsed); + } break; case 'print-quality': case 'print-quality-supported': case 'print-quality-default': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'draft'; break; @@ -1453,7 +1594,8 @@ class PrintIPP extends BasicIPP { } break; case 'printer-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'idle'; break; @@ -1463,13 +1605,16 @@ class PrintIPP extends BasicIPP { case 0x05: $value = 'stopped'; break; - } + } if ($value_parsed > 0x05) + { $value = sprintf('Unknown(IETF standards track "printer-state" reserved): 0x%x',$value_parsed); + } break; - + case 'operations-supported': - switch($value_parsed) { + switch($value_parsed) + { case 0x0000: case 0x0001: $value = sprintf('Unknown(reserved) : %s',ord($value)); @@ -1602,20 +1747,31 @@ class PrintIPP extends BasicIPP { break; } if ($value_parsed > 0x002B && $value_parsed <= 0x3FFF) + { $value = sprintf('Unknown(IETF standards track operations reserved): 0x%x',$value_parsed); - elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) { - if (method_exists($this,'_getEnumVendorExtensions')) { + } + elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) + { + if (method_exists($this,'_getEnumVendorExtensions')) + { $value = $this->_getEnumVendorExtensions($value_parsed); - } else + } + else + { $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed); - } elseif ($value_parsed > 0x8FFF) + } + } + elseif ($value_parsed > 0x8FFF) + { $value = sprintf('Unknown operation (should not exists): 0x%x',$value_parsed); - + } + break; case 'finishings': case 'finishings-default': case 'finishings-supported': - switch ($value_parsed) { + switch ($value_parsed) + { case 3: $value = 'none'; break; @@ -1673,15 +1829,18 @@ class PrintIPP extends BasicIPP { case 31: $value = 'staple-dual-bottom'; break; - } + } if ($value_parsed > 31) + { $value = sprintf('Unknown(IETF standards track "finishing" reserved): 0x%x',$value_parsed); + } break; - + case 'orientation-requested': case 'orientation-requested-supported': case 'orientation-requested-default': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'portrait'; break; @@ -1694,77 +1853,87 @@ class PrintIPP extends BasicIPP { case 0x06: $value = 'reverse-portrait'; break; - } + } if ($value_parsed > 0x06) + { $value = sprintf('Unknown(IETF standards track "orientation" reserved): 0x%x',$value_parsed); + } break; - + default: break; - } - return $value; + } + return $value; } - // }}} - - // {{{ _getJobId () - protected function _getJobId () { - + + protected function _getJobId () + { if (!isset($this->serveroutput->response)) + { $this->jobs = array_merge($this->jobs,array('NO JOB')); - + } + $jobfinded = false; for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++) + { if (($this->serveroutput->response[$i]['attributes']) == "job-attributes") + { for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) - if ($this->serveroutput->response[$i][$j]['name'] == "job-id") { + { + if ($this->serveroutput->response[$i][$j]['name'] == "job-id") + { $this->last_job = $this->serveroutput->response[$i][$j]['value']; $this->jobs = array_merge($this->jobs,array($this->serveroutput->response[$i][$j]['value'])); return; - - } - + } + } + } + } } - // }}} - - // {{{ _getJobUri () - protected function _getJobUri () { + protected function _getJobUri () + { if (!isset($this->jobs_uri)) + { $this->jobs_uri = array(); - + } + $jobfinded = false; for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++) + { if (($this->serveroutput->response[$i]['attributes']) == "job-attributes") + { for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) - if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") { + { + if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") + { $this->last_job = $this->serveroutput->response[$i][$j]['value']; $this->jobs_uri = array_merge($this->jobs_uri,array($this->last_job)); return; - - } + } + } + } + } $this->last_job = ''; - } - // }}} - - // {{{ _parseResponse () - protected function _parseResponse () { + + protected function _parseResponse () + { $j = -1; $this->index = 0; - for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) { - - + for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) + { $tag = ord($this->serveroutput->body[$this->_parsing->offset]); - - - if ($tag > 0x0F) { - + + if ($tag > 0x0F) + { self::_readAttribute($j); $this->index ++; continue; - } + } - switch ($tag) { + switch ($tag) + { case 0x01: $j += 1; $this->serveroutput->response[$j]['attributes'] = "operation-attributes"; @@ -1782,7 +1951,9 @@ class PrintIPP extends BasicIPP { $this->serveroutput->response[$j]['attributes'] = "end-of-attributes"; self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n"); if ($this->alert_on_end_tag === 1) + { echo "END tag OK
"; + } $this->response_completed[(count($this->response_completed) -1)] = "completed"; return; case 0x04: @@ -1803,21 +1974,16 @@ class PrintIPP extends BasicIPP { $this->index = 0; $this->_parsing->offset += 1; break; - } - - self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n"); - - } - return; + } + + self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n"); + } + return; } - // }}} - - - /* // NOTICE : HAVE TO READ AGAIN RFC 2911 TO SEE IF IT IS PART OF SERVER'S RESPONSE (CUPS DO NOT) - // {{{ _getPrinterUri () + protected function _getPrinterUri () { for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++) @@ -1833,32 +1999,43 @@ class PrintIPP extends BasicIPP { $this->printers_uri = array_merge($this->printers_uri,array('')); } - // }}} + */ -// REQUEST BUILDING - - // {{{ _stringCancel () - protected function _stringCancel ($job_uri) { + // REQUEST BUILDING + protected function _stringCancel ($job_uri) + { if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); + { + self::setCharset(); + } if (!isset($this->setup->datatype)) + { self::setBinary(); + } if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!$this->requesting_user) + { self::setUserName(); + } if (!isset($this->meta->message)) + { $this->meta->message = ''; + } self::_setOperationId(); - + self::_setJobUri($job_uri); - + if (!isset($this->error_generation->request_body_malformed)) + { $this->error_generation->request_body_malformed = ""; - + } + $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number . chr(0x00) . chr (0x08) // cancel-Job | operation-id . $this->meta->operation_id // request-id @@ -1874,16 +2051,4 @@ class PrintIPP extends BasicIPP { self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob)); return TRUE; } - // }}} - - -}; - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> +} diff --git a/htdocs/includes/printipp/http_class.php b/htdocs/includes/printipp/http_class.php index 569d4f6648f..30bb33d663b 100644 --- a/htdocs/includes/printipp/http_class.php +++ b/htdocs/includes/printipp/http_class.php @@ -29,7 +29,7 @@ */ /** * This class is intended to implement a subset of Hyper Text Transfer Protocol - * (HTTP/1.1) on client side  (currently: POST operation), with file streaming + * (HTTP/1.1) on client side (currently: POST operation), with file streaming * capability. * * It can perform Basic and Digest authentication. @@ -66,48 +66,58 @@ ************************/ class httpException extends Exception { - protected $errno; - public function __construct ($msg, $errno = null) - { - parent::__construct ($msg); - $this->errno = $errno; - } - public function getErrorFormatted () - { - return sprintf ("[http_class]: %s -- "._(" file %s, line %s"), - $this->getMessage (), $this->getFile (), $this->getLine ()); - } - public function getErrno () - { - return $this->errno; - } + protected $errno; + + public function __construct ($msg, $errno = null) + { + parent::__construct ($msg); + $this->errno = $errno; + } + + public function getErrorFormatted () + { + return sprintf ("[http_class]: %s -- "._(" file %s, line %s"), + $this->getMessage (), $this->getFile (), $this->getLine ()); + } + + public function getErrno () + { + return $this->errno; + } } function error2string($value) { - $level_names = array( - E_ERROR => 'E_ERROR', - E_WARNING => 'E_WARNING', - E_PARSE => 'E_PARSE', - E_NOTICE => 'E_NOTICE', - E_CORE_ERROR => 'E_CORE_ERROR', - E_CORE_WARNING => 'E_CORE_WARNING', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', - E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', - E_USER_WARNING => 'E_USER_WARNING', - E_USER_NOTICE => 'E_USER_NOTICE' - ); - if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT'; - $levels=array(); - if(($value&E_ALL)==E_ALL) - { - $levels[]='E_ALL'; - $value&=~E_ALL; - } - foreach($level_names as $level=>$name) - if(($value&$level)==$level) $levels[]=$name; - return implode(' | ',$levels); + $level_names = array( + E_ERROR => 'E_ERROR', + E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', + E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', + E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', + E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', + E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE' + ); + if(defined('E_STRICT')) { + $level_names[E_STRICT]='E_STRICT'; + } + $levels=array(); + if(($value&E_ALL)==E_ALL) + { + $levels[]='E_ALL'; + $value&=~E_ALL; + } + foreach($level_names as $level=>$name) + { + if(($value&$level)==$level) + { + $levels[]=$name; + } + } + return implode(' | ',$levels); } /*********************** @@ -117,499 +127,486 @@ function error2string($value) ************************/ class http_class { - // variables declaration - public $debug; - public $html_debug; - public $timeout = 30; // time waiting for connection, seconds - public $data_timeout = 30; // time waiting for data, milliseconds - public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond - public $force_multipart_form_post; - public $username; - public $password; - public $request_headers = array (); - public $request_body = "Not a useful information"; - public $status; - public $window_size = 1024; // chunk size of data - public $with_exceptions = 0; // compatibility mode for old scripts - public $port; - public $host; - private $default_port = 631; - private $headers; - private $reply_headers = array (); - private $reply_body = array (); - private $connection; - private $arguments; - private $bodystream = array (); - private $last_limit; - private $connected; - private $nc = 1; - private $user_agent = "PRINTIPP/0.81+CVS"; - private $readed_bytes = 0; + // variables declaration + public $debug; + public $html_debug; + public $timeout = 30; // time waiting for connection, seconds + public $data_timeout = 30; // time waiting for data, milliseconds + public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond + public $force_multipart_form_post; + public $username; + public $password; + public $request_headers = array (); + public $request_body = "Not a useful information"; + public $status; + public $window_size = 1024; // chunk size of data + public $with_exceptions = 0; // compatibility mode for old scripts + public $port; + public $host; + private $default_port = 631; + private $headers; + private $reply_headers = array (); + private $reply_body = array (); + private $connection; + private $arguments; + private $bodystream = array (); + private $last_limit; + private $connected; + private $nc = 1; + private $user_agent = "PRINTIPP/0.81+CVS"; + private $readed_bytes = 0; - public function __construct () - { - true; - } - - /********************* - * - * Public functions - * - **********************/ - - public function GetRequestArguments ($url, &$arguments) - { - $this->arguments = array (); - $arguments["URL"] = $this->arguments["URL"] = $url; - $arguments["RequestMethod"] = $this->arguments["RequestMethod"] = "POST"; - $this->headers["Content-Length"] = 0; - $this->headers["Content-Type"] = "application/octet-stream"; - $this->headers["Host"] = $this->host; - $this->headers["User-Agent"] = $this->user_agent; - //$this->headers["Expect"] = "100-continue"; - - } - - public function Open ($arguments) - { - $this->connected = false; - $url = $arguments["URL"]; - $port = $this->default_port; - #$url = split (':', $url, 2); - $url = preg_split ('#:#', $url, 2); - $transport_type = $url[0]; - $unix = false; - switch ($transport_type) - { - case 'http': - $transport_type = 'tcp://'; - break; - - case 'https': - $transport_type = 'tls://'; - break; - - case 'unix': - $transport_type = 'unix://'; - $port = 0; - $unix = true; - break; - - default: - $transport_type = 'tcp://'; - break; - } - $url = $url[1]; - if (!$unix) - { - #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); - $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2); - $url = $url[0]; - $port = $this->port; - $error = sprintf (_("Cannot resolve url: %s"), $url); - $ip = gethostbyname ($url); - $ip = @gethostbyaddr ($ip); - if (!$ip) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - if (strstr ($url, ":")) // we got an ipv6 address - if (!strstr ($url, "[")) // it is not escaped - $url = sprintf ("[%s]", $url); - } - $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout); - $error = - sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type, - $url, $port, $errstr); - if (!$this->connection) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - $this->connected = true; - return array (true, "success"); - } - - public function SendRequest ($arguments) - { - $error = - sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error." ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - if (!preg_match ('#http/1.1 401 unauthorized#', $this->status)) - { - return array (true, "success"); - } - $headers = array_keys ($this->reply_headers); - $error = _("need authentication but no mechanism provided"); - if (!in_array ("www-authenticate", $headers)) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - #$authtype = split (' ', $this->reply_headers["www-authenticate"]); - $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]); - $authtype = strtolower ($authtype[0]); - switch ($authtype) - { - case 'basic': - $pass = base64_encode ($this->user.":".$this->password); - $arguments["Headers"]["Authorization"] = "Basic ".$pass; - break; - - case 'digest': - $arguments["Headers"]["Authorization"] = self::_BuildDigest (); - break; - - default: - $error = - sprintf (_("need '%s' authentication mechanism, but have not"), - $authtype[0]); - return $this->_HttpError ($error, E_USER_WARNING); - break; - - } - self::Close (); - self::Open ($arguments); - $error = - sprintf (_ - ('Streaming request failed to %s after a try to authenticate'), - $url); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - return array (true, "success"); - } - - public function ReadReplyHeaders (&$headers) - { - $headers = $this->reply_headers; - } - - public function ReadReplyBody (&$body, $chunk_size) - { - $body = substr ($this->reply_body, $this->last_limit, $chunk_size); - $this->last_limit += $chunk_size; - } - - public function Close () - { - if (!$this->connected) - return; - fclose ($this->connection); - } - - /********************* - * - * Private functions - * - *********************/ - - private function _HttpError ($msg, $level, $errno = null) - { - $trace = ''; - $backtrace = debug_backtrace; - foreach ($backtrace as $trace) - { - $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']); - } - $msg = sprintf ( '%s\n%s: [errno: %s]: %s', - $trace, error2string ($level), $errno, $msg); - if ($this->with_exceptions) - { - throw new httpException ($msg, $errno); - } - else - { - trigger_error ($msg, $level); - return array (false, $msg); - } - } - - private function _streamString ($string) - { - $success = fwrite ($this->connection, $string); - if (!$success) - { - return false; - } - return true; - } - - private function _StreamRequest ($arguments) - { - $this->status = false; - $this->reply_headers = array (); - $this->reply_body = ""; - if (!$this->connected) - { - return _HttpError (_("not connected"), E_USER_WARNING); - } - $this->arguments = $arguments; - $content_length = 0; - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $length = strlen ($value); - } - elseif ($type == "File") - { - if (is_readable ($value)) + public function __construct () { - $length = filesize ($value); + true; } - else + + /********************* + * + * Public functions + * + **********************/ + + public function GetRequestArguments ($url, &$arguments) { - $length = 0; - return - _HttpError (sprintf (_("%s: file is not readable"), $value), - E_USER_WARNING); + $this->arguments = array (); + $this->arguments["URL"] = $arguments["URL"] = $url; + $this->arguments["RequestMethod"] = $arguments["RequestMethod"] = "POST"; + $this->headers["Content-Length"] = 0; + $this->headers["Content-Type"] = "application/octet-stream"; + $this->headers["Host"] = $this->host; + $this->headers["User-Agent"] = $this->user_agent; + //$this->headers["Expect"] = "100-continue"; } - } - else - { - $length = 0; - return - _HttpError (sprintf - (_("%s: not a valid argument for content"), $type), - E_USER_WARNING); - } - $content_length += $length; - } - $this->request_body = sprintf (_("%s Bytes"), $content_length); - $this->headers["Content-Length"] = $content_length; - $this->arguments["Headers"] = - array_merge ($this->headers, $this->arguments["Headers"]); - if ($this->arguments["RequestMethod"] != "POST") - { - return - _HttpError (sprintf - (_("%s: method not implemented"), - $arguments["RequestMethod"]), E_USER_WARNING); - } - $string = - sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); - $this->request_headers[$string] = ''; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while puts POST operation"), - E_USER_WARNING); - } - foreach ($this->arguments["Headers"] as $header => $value) - { - $string = sprintf ("%s: %s\r\n", $header, $value); - $this->request_headers[$header] = $value; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while puts HTTP headers"), - E_USER_WARNING); - } - } - $string = "\r\n"; - if (!$this->_streamString ($string)) - { - return _HttpError (_("Error while ends HTTP headers"), - E_USER_WARNING); - } - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $streamed_length = 0; - while ($streamed_length < strlen ($value)) + + public function Open ($arguments) { - $string = substr ($value, $streamed_length, $this->window_size); - if (!$this->_streamString ($string)) - { - return _HttpError (_("error while sending body data"), - E_USER_WARNING); - } - $streamed_length += $this->window_size; + $this->connected = false; + $url = $arguments["URL"]; + $port = $this->default_port; + #$url = split (':', $url, 2); + $url = preg_split ('#:#', $url, 2); + $transport_type = $url[0]; + $unix = false; + switch ($transport_type) + { + case 'http': + $transport_type = 'tcp://'; + break; + + case 'https': + $transport_type = 'tls://'; + break; + + case 'unix': + $transport_type = 'unix://'; + $port = 0; + $unix = true; + break; + + default: + $transport_type = 'tcp://'; + break; + } + $url = $url[1]; + if (!$unix) + { + #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); + $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2); + $url = $url[0]; + $port = $this->port; + $error = sprintf (_("Cannot resolve url: %s"), $url); + $ip = gethostbyname ($url); + $ip = @gethostbyaddr ($ip); + if (!$ip) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + if (strstr ($url, ":")) // we got an ipv6 address + { + if (!strstr ($url, "[")) // it is not escaped + { + $url = sprintf ("[%s]", $url); + } + } + } + $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout); + $error = + sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type, + $url, $port, $errstr); + if (!$this->connection) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + $this->connected = true; + return array (true, "success"); } - } - elseif ($type == "File") - { - if (is_readable ($value)) + + public function SendRequest ($arguments) { - $file = fopen ($value, 'rb'); - while (!feof ($file)) - { - if (gettype ($block = @fread ($file, $this->window_size)) != - "string") - { - return _HttpError (_("cannot read file to upload"), - E_USER_WARNING); - } - if (!$this->_streamString ($block)) - { - return _HttpError (_("error while sending body data"), - E_USER_WARNING); - } - } + $error = + sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']); + $result = self::_StreamRequest ($arguments); + if (!$result[0]) + { + return $this->_HttpError ($error." ".$result[1], E_USER_WARNING); + } + self::_ReadReply (); + if (!preg_match ('#http/1.1 401 unauthorized#', $this->status)) + { + return array (true, "success"); + } + $headers = array_keys ($this->reply_headers); + $error = _("need authentication but no mechanism provided"); + if (!in_array ("www-authenticate", $headers)) + { + return $this->_HttpError ($error, E_USER_WARNING); + } + #$authtype = split (' ', $this->reply_headers["www-authenticate"]); + $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]); + $authtype = strtolower ($authtype[0]); + switch ($authtype) + { + case 'basic': + $pass = base64_encode ($this->user.":".$this->password); + $arguments["Headers"]["Authorization"] = "Basic ".$pass; + break; + + case 'digest': + $arguments["Headers"]["Authorization"] = self::_BuildDigest (); + break; + + default: + $error = + sprintf (_("need '%s' authentication mechanism, but have not"), + $authtype[0]); + return $this->_HttpError ($error, E_USER_WARNING); + break; + } + self::Close (); + self::Open ($arguments); + + $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']); + $result = self::_StreamRequest ($arguments); + if (!$result[0]) + { + return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); + } + self::_ReadReply (); + return array (true, "success"); } - } - } - return array (true, "success"); - } - private function _ReadReply () - { - if (!$this->connected) - { - return array (false, _("not connected")); - } - $this->reply_headers = array (); - $this->reply_body = ""; - $headers = array (); - $body = ""; - while (!feof ($this->connection)) - { - $line = fgets ($this->connection, 1024); - if (strlen (trim($line)) == 0) - break; // \r\n => end of headers - if (preg_match ('#^[[:space:]]#', $line)) - { - $headers[-1] .= sprintf(' %s', trim ($line)); - continue; - } - $headers[] = trim ($line); - } - $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false; - foreach ($headers as $header) - { - $header = preg_split ("#: #", $header); - $header[0] = strtolower ($header[0]); - if ($header[0] !== "www-authenticate") - { - $header[1] = isset ($header[1]) ? strtolower ($header[1]) : ""; - } - if (!isset ($this->reply_headers[$header[0]])) - { - $this->reply_headers[$header[0]] = $header[1]; - } - } - self::_ReadStream (); - return true; - } + public function ReadReplyHeaders (&$headers) + { + $headers = $this->reply_headers; + } - private function _ReadStream () - { - if (! array_key_exists ("content-length", $this->reply_headers)) - { - stream_set_blocking($this->connection, 0); - $this->reply_body = stream_get_contents($this->connection); - return true; - } - stream_set_blocking($this->connection, 1); - $content_length = $this->reply_headers["content-length"]; - $this->reply_body = stream_get_contents($this->connection,$content_length); - return true; - } + public function ReadReplyBody (&$body, $chunk_size) + { + $body = substr ($this->reply_body, $this->last_limit, $chunk_size); + $this->last_limit += $chunk_size; + } - private function _BuildDigest () - { - $auth = $this->reply_headers["www-authenticate"]; - #list ($head, $auth) = split (" ", $auth, 2); - list ($head, $auth) = preg_split ("# #", $auth, 2); - #$auth = split (", ", $auth); - $auth = preg_split ("#, #", $auth); - foreach ($auth as $sheme) - { - #list ($sheme, $value) = split ('=', $sheme); - list ($sheme, $value) = preg_split ('#=#', $sheme); - $fields[$sheme] = trim (trim ($value), '"'); - } - $nc = sprintf ('%x', $this->nc); - $prepend = ""; - while ((strlen ($nc) + strlen ($prepend)) < 8) - $prependi .= "0"; - $nc = $prepend.$nc; - $cnonce = "printipp"; - $username = $this->user; - $password = $this->password; - $A1 = $username.":".$fields["realm"].":".$password; - if (array_key_exists ("algorithm", $fields)) - { - $algorithm = strtolower ($fields["algorithm"]); - switch ($algorithm) - { - case "md5": - break; + public function Close () + { + if (!$this->connected) + { + return; + } + fclose ($this->connection); + } - case "md5-sess": - $A1 = - $username.":".$fields["realm"].":".$password.":". - $fields['nonce'].":".$cnonce; - break; + /********************* + * + * Private functions + * + *********************/ - default: - return _HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $algorithm), - E_USER_WARNING); - return false; - break; - } - } - $A2 = "POST:".$this->arguments["RequestURI"]; - if (array_key_exists ("qop", $fields)) - { - $qop = strtolower ($fields["qop"]); - #$qop = split (" ", $qop); - $qop = preg_split ("# #", $qop); - if (in_array ("auth", $qop)) - $qop = "auth"; - else - { - self::_HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $qop), - E_USER_WARNING); - return false; - } - } - $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2)); - if (isset ($qop) && ($qop == "auth")) - { - $response = - md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. - ":".$A2); - } - $auth_scheme = - sprintf - ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', - $username, $fields["realm"], $fields['nonce'], - $this->arguments["RequestURI"], $response); - if (isset ($algorithm)) - $auth_scheme .= sprintf (', algorithm="%s"', $algorithm); - if (isset ($qop)) - $auth_scheme .= sprintf (', cnonce="%s"', $cnonce); - if (array_key_exists ("opaque", $fields)) - $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']); - if (isset ($qop)) - $auth_scheme .= sprintf (', qop="%s"', $qop); - $auth_scheme .= sprintf (', nc=%s', $nc); - $this->nc++; - return $auth_scheme; - } + private function _HttpError ($msg, $level, $errno = null) + { + $trace = ''; + $backtrace = debug_backtrace(); + foreach ($backtrace as $trace) + { + $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']); + } + $msg = sprintf ( '%s\n%s: [errno: %s]: %s', + $trace, error2string ($level), $errno, $msg); + if ($this->with_exceptions) + { + throw new httpException ($msg, $errno); + } + else + { + trigger_error ($msg, $level); + return array (false, $msg); + } + } -}; + private function _streamString ($string) + { + $success = fwrite ($this->connection, $string); + if (!$success) + { + return false; + } + return true; + } -/* - * Local variables: - * mode: php - * tab-width: 2 - * c-basic-offset: 2 - * End: - */ -?> + private function _StreamRequest ($arguments) + { + $this->status = false; + $this->reply_headers = array (); + $this->reply_body = ""; + if (!$this->connected) + { + return $this->_HttpError (_("not connected"), E_USER_WARNING); + } + $this->arguments = $arguments; + $content_length = 0; + foreach ($this->arguments["BodyStream"] as $argument) + { + list ($type, $value) = each ($argument); + reset ($argument); + if ($type == "Data") + { + $length = strlen ($value); + } + elseif ($type == "File") + { + if (is_readable ($value)) + { + $length = filesize ($value); + } + else + { + $length = 0; + return $this->_HttpError (sprintf (_("%s: file is not readable"), $value), E_USER_WARNING); + } + } + else + { + $length = 0; + return $this->_HttpError (sprintf(_("%s: not a valid argument for content"), $type), E_USER_WARNING); + } + $content_length += $length; + } + $this->request_body = sprintf (_("%s Bytes"), $content_length); + $this->headers["Content-Length"] = $content_length; + $this->arguments["Headers"] = array_merge ($this->headers, $this->arguments["Headers"]); + if ($this->arguments["RequestMethod"] != "POST") + { + return $this->_HttpError (sprintf(_("%s: method not implemented"), $arguments["RequestMethod"]), E_USER_WARNING); + } + $string = sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); + $this->request_headers[$string] = ''; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while puts POST operation"), E_USER_WARNING); + } + foreach ($this->arguments["Headers"] as $header => $value) + { + $string = sprintf ("%s: %s\r\n", $header, $value); + $this->request_headers[$header] = $value; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while puts HTTP headers"), E_USER_WARNING); + } + } + $string = "\r\n"; + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("Error while ends HTTP headers"), E_USER_WARNING); + } + foreach ($this->arguments["BodyStream"] as $argument) + { + list ($type, $value) = each ($argument); + reset ($argument); + if ($type == "Data") + { + $streamed_length = 0; + while ($streamed_length < strlen ($value)) + { + $string = substr ($value, $streamed_length, $this->window_size); + if (!$this->_streamString ($string)) + { + return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); + } + $streamed_length += $this->window_size; + } + } + elseif ($type == "File") + { + if (is_readable ($value)) + { + $file = fopen ($value, 'rb'); + while (!feof ($file)) + { + if (gettype ($block = @fread ($file, $this->window_size)) != "string") + { + return $this->_HttpError (_("cannot read file to upload"), E_USER_WARNING); + } + if (!$this->_streamString ($block)) + { + return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); + } + } + } + } + } + return array (true, "success"); + } + + private function _ReadReply () + { + if (!$this->connected) + { + return array (false, _("not connected")); + } + $this->reply_headers = array (); + $this->reply_body = ""; + $headers = array (); + $body = ""; + while (!feof ($this->connection)) + { + $line = fgets ($this->connection, 1024); + if (strlen (trim($line)) == 0) + { + break; + } // \r\n => end of headers + if (preg_match ('#^[[:space:]]#', $line)) + { + $headers[-1] .= sprintf(' %s', trim ($line)); + continue; + } + $headers[] = trim ($line); + } + $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false; + foreach ($headers as $header) + { + $header = preg_split ("#: #", $header); + $header[0] = strtolower ($header[0]); + if ($header[0] !== "www-authenticate") + { + $header[1] = isset ($header[1]) ? strtolower ($header[1]) : ""; + } + if (!isset ($this->reply_headers[$header[0]])) + { + $this->reply_headers[$header[0]] = $header[1]; + } + } + self::_ReadStream (); + return true; + } + + private function _ReadStream () + { + if (! array_key_exists ("content-length", $this->reply_headers)) + { + stream_set_blocking($this->connection, 0); + $this->reply_body = stream_get_contents($this->connection); + return true; + } + stream_set_blocking($this->connection, 1); + $content_length = $this->reply_headers["content-length"]; + $this->reply_body = stream_get_contents($this->connection,$content_length); + return true; + } + + private function _BuildDigest () + { + $auth = $this->reply_headers["www-authenticate"]; + #list ($head, $auth) = split (" ", $auth, 2); + list ($head, $auth) = preg_split ("# #", $auth, 2); + #$auth = split (", ", $auth); + $auth = preg_split ("#, #", $auth); + foreach ($auth as $sheme) + { + #list ($sheme, $value) = split ('=', $sheme); + list ($sheme, $value) = preg_split ('#=#', $sheme); + $fields[$sheme] = trim (trim ($value), '"'); + } + $nc = sprintf ('%x', $this->nc); + $prepend = ""; + while ((strlen ($nc) + strlen ($prepend)) < 8) + $prependi .= "0"; + $nc = $prepend.$nc; + $cnonce = "printipp"; + $username = $this->user; + $password = $this->password; + $A1 = $username.":".$fields["realm"].":".$password; + if (array_key_exists ("algorithm", $fields)) + { + $algorithm = strtolower ($fields["algorithm"]); + switch ($algorithm) + { + case "md5": + break; + + case "md5-sess": + $A1 = + $username.":".$fields["realm"].":".$password.":". + $fields['nonce'].":".$cnonce; + break; + + default: + return $this->_HttpError( + sprintf (_("digest Authorization: algorithm '%s' not implemented"), + $algorithm), + E_USER_WARNING); + return false; + break; + } + } + $A2 = "POST:".$this->arguments["RequestURI"]; + if (array_key_exists ("qop", $fields)) + { + $qop = strtolower ($fields["qop"]); + #$qop = split (" ", $qop); + $qop = preg_split ("# #", $qop); + if (in_array ("auth", $qop)) + { + $qop = "auth"; + } + else + { + self::_HttpError( + sprintf (_("digest Authorization: algorithm '%s' not implemented"), + $qop), + E_USER_WARNING); + return false; + } + } + $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2)); + if (isset ($qop) && ($qop == "auth")) + { + $response = + md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. + ":".$A2); + } + $auth_scheme = + sprintf + ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', + $username, $fields["realm"], $fields['nonce'], + $this->arguments["RequestURI"], $response); + if (isset ($algorithm)) + { + $auth_scheme .= sprintf (', algorithm="%s"', $algorithm); + } + if (isset ($qop)) + { + $auth_scheme .= sprintf (', cnonce="%s"', $cnonce); + } + if (array_key_exists ("opaque", $fields)) + { + $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']); + } + if (isset ($qop)) + { + $auth_scheme .= sprintf (', qop="%s"', $qop); + } + $auth_scheme .= sprintf (', nc=%s', $nc); + $this->nc++; + return $auth_scheme; + } +} From 9c2c338dc09e4a6b48ae1f02a9a04a9f856f39a1 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sun, 28 Dec 2014 14:21:54 +0100 Subject: [PATCH 12/61] Typo on variable --- htdocs/core/modules/printing/printgcp.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index 2091c1a89eb..2d4cb8a2c98 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -186,9 +186,9 @@ class printing_printgcp extends PrintingDriver } else { - if (! empty($conf->global->PRINTIPP_GCP_DEFAULT)) + if (! empty($conf->global->PRINTING_GCP_DEFAULT)) { - $printer_id=$conf->global->PRINTIPP_GCP_DEFAULT; + $printer_id=$conf->global->PRINTING_GCP_DEFAULT; } else { From f738863e51fdd35d4aeedcbbaa3c76ea31a8b0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sun, 28 Dec 2014 17:14:11 +0100 Subject: [PATCH 13/61] Revert previous commit --- htdocs/contrat/class/contrat.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index f0ddc71aee0..5265f7025c5 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -51,6 +51,7 @@ class Contrat extends CommonObject var $id; var $ref; + var $ref_ext; var $ref_supplier; var $socid; var $societe; // Objet societe @@ -417,6 +418,7 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi,"; $sql.= " note_private, note_public, model_pdf, extraparams"; $sql.= " ,ref_supplier"; + $sql.= " ,ref_ext"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat"; if ($ref) { @@ -436,6 +438,7 @@ class Contrat extends CommonObject $this->id = $result["rowid"]; $this->ref = (!isset($result["ref"]) || !$result["ref"]) ? $result["rowid"] : $result["ref"]; $this->ref_supplier = $result["ref_supplier"]; + $this->ref_ext = $result["ref_ext"]; $this->statut = $result["statut"]; $this->mise_en_service = $this->db->jdate($result["datemise"]); $this->date_contrat = $this->db->jdate($result["datecontrat"]); @@ -737,7 +740,7 @@ class Contrat extends CommonObject // Insert contract $sql = "INSERT INTO ".MAIN_DB_PREFIX."contrat (datec, fk_soc, fk_user_author, date_contrat,"; $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; - $sql.= " ref, entity, note_private, note_public, ref_supplier)"; + $sql.= " ref, entity, note_private, note_public, ref_supplier, ref_ext)"; $sql.= " VALUES ('".$this->db->idate($now)."',".$this->socid.",".$user->id; $sql.= ", '".$this->db->idate($this->date_contrat)."'"; $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); @@ -748,6 +751,7 @@ class Contrat extends CommonObject $sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); $sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql.= ", ".(!empty($this->ref_supplier)?("'".$this->db->escape($this->ref_supplier)."'"):"NULL"); + $sql.= ", ".(!empty($this->ref_ext)?("'".$this->db->escape($this->ref_ext)."'"):"NULL"); $sql.= ")"; $resql=$this->db->query($sql); if ($resql) @@ -999,6 +1003,7 @@ class Contrat extends CommonObject if (isset($this->ref)) $this->ref=trim($this->ref); if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier); + if (isset($this->ref_ext)) $this->ref_ext=trim($this->ref_ext); if (isset($this->entity)) $this->entity=trim($this->entity); if (isset($this->statut)) $this->statut=trim($this->statut); if (isset($this->fk_soc)) $this->fk_soc=trim($this->fk_soc); @@ -1022,6 +1027,7 @@ class Contrat extends CommonObject $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; $sql.= " ref_supplier=".(isset($this->ref_supplier)?"'".$this->db->escape($this->ref_supplier)."'":"null").","; + $sql.= " ref_ext=".(isset($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null").","; $sql.= " entity=".$conf->entity.","; $sql.= " date_contrat=".(dol_strlen($this->date_contrat)!=0 ? "'".$this->db->idate($this->date_contrat)."'" : 'null').","; $sql.= " statut=".(isset($this->statut)?$this->statut:"null").","; From 98ed7476719459f5a829db0700936a3e488f5403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sun, 28 Dec 2014 17:17:08 +0100 Subject: [PATCH 14/61] Fix: [ bug #1765 ] Unable to create a contract --- htdocs/install/mysql/tables/llx_contrat.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql index 5efbcdfe1fa..0e75c50305b 100644 --- a/htdocs/install/mysql/tables/llx_contrat.sql +++ b/htdocs/install/mysql/tables/llx_contrat.sql @@ -23,6 +23,7 @@ create table llx_contrat rowid integer AUTO_INCREMENT PRIMARY KEY, ref varchar(30), -- contrat reference ref_supplier varchar(30), -- suplier contract ref + ref_ext varchar(30), -- external contract ref entity integer DEFAULT 1 NOT NULL, -- multi company id tms timestamp, datec datetime, -- creation date From 90add2fa9636695eb4f7420f7153f8d14aae5649 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Jan 2015 17:23:52 +0100 Subject: [PATCH 15/61] Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. --- ChangeLog | 1 + htdocs/main.inc.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0a849cce895..5b621467312 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 3.6.3 compared to 3.6.2 ***** - Fix: ref_ext was not saved when recording a customer order from web service +- Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 419c737b270..b17bc913752 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -725,7 +725,7 @@ if (! empty($conf->browser->phone)) // If we force to use jmobile, then we reenable javascript if (! empty($conf->dol_use_jmobile)) $conf->use_javascript_ajax=1; // Disabled bugged themes -if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo'))) +if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo','amarok'))) { $conf->theme='eldy'; $conf->css = "/theme/".$conf->theme."/style.css.php"; From c441aa89db3876758277ca3f272f64c8c007219b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Jan 2015 18:19:44 +0100 Subject: [PATCH 16/61] Fixed: Avoid warning --- htdocs/core/modules/DolibarrModules.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index e25f4d0c715..8b636fd247f 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -748,6 +748,8 @@ abstract class DolibarrModules $err=0; + if (empty($this->const)) return 0; + foreach ($this->const as $key => $value) { $name = $this->const[$key][0]; @@ -816,6 +818,8 @@ abstract class DolibarrModules $err=0; + if (empty($this->const)) return 0; + foreach ($this->const as $key => $value) { $name = $this->const[$key][0]; From b6b84e235c5466fe009c5cbd1c3797c735c60219 Mon Sep 17 00:00:00 2001 From: BENKE Charles Date: Mon, 12 Jan 2015 10:16:34 +0100 Subject: [PATCH 17/61] Update card.php hide line with empty duration if FICHINTER_HIDE_EMPTY_DURATION is activate --- htdocs/fichinter/card.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 4ffc31c9cab..ed4ceeb1cf1 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1373,6 +1373,8 @@ else if ($id > 0 || ! empty($ref)) $sql.= ' ft.date as date_intervention'; $sql.= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft'; $sql.= ' WHERE ft.fk_fichinter = '.$object->id; + if (!empty($conf->global->FICHINTER_HIDE_EMPTY_DURATION)) + $sql.= ' AND ft.duree <> 0'; $sql.= ' ORDER BY ft.rang ASC, ft.rowid'; $resql = $db->query($sql); From 26cad2400eea91656650f15169815c4663a7f6cd Mon Sep 17 00:00:00 2001 From: Cedric Date: Mon, 12 Jan 2015 13:18:50 +0100 Subject: [PATCH 18/61] Fix missing lang key --- htdocs/langs/en_US/main.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 9b8f06f262e..bc962c41846 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -258,6 +258,7 @@ days=days Hours=Hours Minutes=Minutes Seconds=Seconds +Weeks=Weeks Today=Today Yesterday=Yesterday Tomorrow=Tomorrow From d2cd841573110cb5a57746ce077aea5cf7890103 Mon Sep 17 00:00:00 2001 From: Cedric Date: Mon, 12 Jan 2015 13:23:18 +0100 Subject: [PATCH 19/61] Fix divide by zero error --- htdocs/cron/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 0a68ca211b9..79306fb1d65 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -354,7 +354,7 @@ if (($action=="create") || ($action=="edit")) print $langs->trans('CronEvery').""; print "'; @@ -621,9 +619,6 @@ class FormCompany print ''; } print ajax_autocompleter(($socid?$socid:-1),$htmlname,DOL_URL_ROOT.'/societe/ajaxcompanies.php','',$minLength); - print ''; - print ''; - print ''; print "\n"; return $socid; } From ed839114ab3b4fcc7f27f8a31f6c04c948af22b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 18:42:19 +0100 Subject: [PATCH 38/61] Fixed loading of external numeration modules in FactureFournisseur and Propal --- htdocs/comm/propal/class/propal.class.php | 13 ++++++++----- htdocs/fourn/class/fournisseur.facture.class.php | 10 +++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 846bb5acb10..84b0f65d679 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2564,11 +2564,14 @@ class Propal extends CommonObject $classname = $conf->global->PROPALE_ADDON; // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/propale/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/propale/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; } if (! $mybool) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 786d619665e..918baea1425 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1497,10 +1497,14 @@ class FactureFournisseur extends CommonInvoice $file = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER.".php"; $classname = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER; + // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/supplier_invoice/"; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/supplier_invoice/"); + // Load file with numbering class (if found) $mybool|=@include_once $dir.$file; } From 41e01a22a3dfb5aa762ec212d3199f04a21f51b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 18:58:05 +0100 Subject: [PATCH 39/61] Fixed loading of external numeration modules in Contrat, Commande, Facture, Contrat, Expedition, Fichinter, CommandeFournisseur and uniformized code --- htdocs/commande/class/commande.class.php | 17 ++-- htdocs/compta/facture/class/facture.class.php | 80 +++++++++++-------- htdocs/contrat/class/contrat.class.php | 38 +++++---- htdocs/expedition/class/expedition.class.php | 43 ++++++---- htdocs/fichinter/class/fichinter.class.php | 29 ++++--- .../class/fournisseur.commande.class.php | 54 +++++++------ 6 files changed, 155 insertions(+), 106 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 52e454bf14e..573778e808c 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -137,17 +137,20 @@ class Commande extends CommonOrder $classname = $conf->global->COMMANDE_ADDON; // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/commande/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/commande/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; } if (! $mybool) { - dol_print_error('',"Failed to include file ".$file); - return ''; + dol_print_error('',"Failed to include file ".$file); + return ''; } $obj = new $classname(); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 1df0696486c..63cdcaeb865 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2504,52 +2504,64 @@ class Facture extends CommonInvoice else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; - $mybool=false; - - $file = $conf->global->FACTURE_ADDON.".php"; - $classname = $conf->global->FACTURE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) + if (! empty($conf->global->FACTURE_ADDON)) { - $dir = $dirroot."/core/modules/facture/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } + $mybool=false; + + $file = $conf->global->FACTURE_ADDON.".php"; + $classname = $conf->global->FACTURE_ADDON; - // For compatibility - if (! $mybool) - { - $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; - $classname = "mod_facture_".$conf->global->FACTURE_ADDON; - $classname = preg_replace('/\-.*$/','',$classname); // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/facture/"); + // Load file with numbering class (if found) $mybool|=@include_once $dir.$file; } - } - //print "xx".$mybool.$dir.$file."-".$classname; - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } + // For compatibility + if (! $mybool) + { + $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; + $classname = "mod_facture_".$conf->global->FACTURE_ADDON; + $classname = preg_replace('/\-.*$/','',$classname); + // Include file with class + foreach ($conf->file->dol_document_root as $dirroot) + { + $dir = $dirroot."/core/modules/facture/"; + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + } - $obj = new $classname(); - $numref = ""; - $numref = $obj->getNumRef($soc,$this,$mode); + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - if ($numref != "") - { - return $numref; + $obj = new $classname(); + $numref = ""; + $numref = $obj->getNextValue($soc,$this,$mode); + + if ($numref != "") + { + return $numref; + } + else + { + dol_print_error($db,"Facture::getNextNumRef ".$obj->error); + return ""; + } } else { - //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); - return false; + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); + return ""; } } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 6cf04c10522..3e4605a8f2c 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -92,23 +92,31 @@ class Contrat extends CommonObject global $db, $langs, $conf; $langs->load("contracts"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/contract"; - - if (empty($conf->global->CONTRACT_ADDON)) + if (!empty($conf->global->CONTRACT_ADDON)) { - $conf->global->CONTRACT_ADDON='mod_contract_serpis'; - } + $mybool = false; - $file = $conf->global->CONTRACT_ADDON.".php"; + $file = $conf->global->CONTRACT_ADDON.".php"; + $classname = $conf->global->CONTRACT_ADDON; - // Chargement de la classe de numerotation - $classname = $conf->global->CONTRACT_ADDON; + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/contract/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $result=include_once $dir.'/'.$file; - if ($result) - { $obj = new $classname(); - $numref = ""; $numref = $obj->getNextValue($soc,$this); @@ -118,15 +126,17 @@ class Contrat extends CommonObject } else { + $this->error = $obj->error; dol_print_error($db,get_class($this)."::getNextValue ".$obj->error); return ""; } } else { - print $langs->trans("Error")." ".$langs->trans("Error_CONTRACT_ADDON_NotDefined"); + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); return ""; - } + } } /** diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index b6cdf5457d3..1045bed42be 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -119,21 +119,30 @@ class Expedition extends CommonObject global $db, $langs, $conf; $langs->load("sendings"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/expedition"; - - if (empty($conf->global->EXPEDITION_ADDON_NUMBER)) + if (!empty($conf->global->EXPEDITION_ADDON_NUMBER)) { - $conf->global->EXPEDITION_ADDON_NUMBER='mod_expedition_safor'; - } + $mybool = false; - $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php"; + $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php"; + $classname = $conf->global->EXPEDITION_ADDON_NUMBER; - // Chargement de la classe de numerotation - $classname = $conf->global->EXPEDITION_ADDON_NUMBER; + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/expedition/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $result=include_once $dir.'/'.$file; - if ($result) - { $obj = new $classname(); $numref = ""; $numref = $obj->getNextValue($soc,$this); @@ -147,12 +156,12 @@ class Expedition extends CommonObject dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); return ""; } - } - else - { - print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); - return ""; - } + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined"); + return ""; + } } /** diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 5c556ff2356..42c9208ff08 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -599,25 +599,33 @@ class Fichinter extends CommonObject global $conf, $db, $langs; $langs->load("interventions"); - $dir = DOL_DOCUMENT_ROOT . "/core/modules/fichinter/"; - if (! empty($conf->global->FICHEINTER_ADDON)) { + $mybool = false; + $file = $conf->global->FICHEINTER_ADDON.".php"; $classname = $conf->global->FICHEINTER_ADDON; - if (! file_exists($dir.$file)) - { - $file='mod_'.$file; - $classname='mod_'.$classname; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/fichinter/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; } - // Chargement de la classe de numerotation - require_once $dir.$file; + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } $obj = new $classname(); - $numref = ""; - $numref = $obj->getNumRef($soc,$this); + $numref = $obj->getNextValue($soc,$this); if ( $numref != "") { @@ -631,6 +639,7 @@ class Fichinter extends CommonObject } else { + $langs->load("errors"); print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined"); return ""; } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 3aa9d77f5de..8e618ba0eee 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -551,44 +551,50 @@ class CommandeFournisseur extends CommonOrder global $db, $langs, $conf; $langs->load("orders"); - $dir = DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/'; - if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) { + $mybool = false; + $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php'; + $classname=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; - if (is_readable($dir.'/'.$file)) + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/supplier_order/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) { - // Definition du nom de modele de numerotation de commande fournisseur - $modName=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; - require_once $dir.'/'.$file; + dol_print_error('',"Failed to include file ".$file); + return ''; + } - // Recuperation de la nouvelle reference - $objMod = new $modName($this->db); + $obj = new $classname(); + $numref = ""; + $numref = $obj->getNextValue($soc,$this); - $numref = ""; - $numref = $objMod->commande_get_num($soc,$this); - - if ( $numref != "") - { - return $numref; - } - else - { - dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error); - return -1; - } + if ( $numref != "") + { + return $numref; } else { - print $langs->trans("Error")." ".$langs->trans("Error_FailedToLoad_COMMANDE_SUPPLIER_ADDON_File",$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER); - return -2; + $this->error = $obj->error; + dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error); + return ""; } } else { - print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_SUPPLIER_ADDON_NotDefined"); - return -3; + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); + return ""; } } From 103a433bdf912cb8bacd819f7a4192e2b778ccb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 19:00:44 +0100 Subject: [PATCH 40/61] Fix: [ bug #1796 ] Unable to use numeration modules from an external module --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 2a49b467783..6b25a471b81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules +- Fix: [ bug #1796 ] Unable to use numeration modules from an external module ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. From cc9197e4c85df1daae9c66dbdddd20348d9c1f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 19:13:38 +0100 Subject: [PATCH 41/61] Fixed problem with Fichinter::getNextNumRef --- htdocs/fichinter/class/fichinter.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 42c9208ff08..c1ec1bef0fc 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -603,8 +603,8 @@ class Fichinter extends CommonObject { $mybool = false; - $file = $conf->global->FICHEINTER_ADDON.".php"; - $classname = $conf->global->FICHEINTER_ADDON; + $file = "mod_".$conf->global->FICHEINTER_ADDON.".php"; + $classname = "mod_".$conf->global->FICHEINTER_ADDON; // Include file with class $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); From 7f59cf919403d858f00fd3028e6eab875b03d96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 19:28:27 +0100 Subject: [PATCH 42/61] Fix: [ bug #1787 ] Incorrect behaviour of doActions hook --- ChangeLog | 1 + htdocs/adherents/fiche.php | 942 ++++----- htdocs/comm/fiche.php | 132 +- htdocs/comm/mailing/fiche.php | 902 ++++---- htdocs/comm/propal.php | 1704 +++++++-------- htdocs/comm/prospect/list.php | 12 +- htdocs/commande/fiche.php | 2137 +++++++++---------- htdocs/compta/facture.php | 3289 +++++++++++++++-------------- htdocs/compta/paiement.php | 330 +-- htdocs/expedition/fiche.php | 882 ++++---- htdocs/fourn/facture/paiement.php | 262 +-- htdocs/fourn/fiche.php | 57 +- htdocs/product/document.php | 12 +- htdocs/product/fournisseurs.php | 204 +- htdocs/resource/card.php | 69 +- 15 files changed, 5480 insertions(+), 5455 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a49b467783..e19f3947a59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules +- Fix: [ bug #1787 ] Incorrect behaviour of doActions hook ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. diff --git a/htdocs/adherents/fiche.php b/htdocs/adherents/fiche.php index ef04edeeb53..97d71d1572a 100644 --- a/htdocs/adherents/fiche.php +++ b/htdocs/adherents/fiche.php @@ -121,556 +121,558 @@ $hookmanager->initHooks(array('membercard')); $parameters=array('rowid'=>$rowid, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) -{ - $error=0; - if (empty($user->rights->user->user->creer)) // If can edit only itself user, we can link to itself only - { - if ($userid != $user->id && $userid != $object->user_id) - { - $error++; - $mesg='
'.$langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly").'
'; - } - } +if (empty($reshook)) { - if (! $error) + if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) { - if ($userid != $object->user_id) // If link differs from currently in database + $error=0; + if (empty($user->rights->user->user->creer)) // If can edit only itself user, we can link to itself only { - $result=$object->setUserId($userid); - if ($result < 0) dol_print_error($object->db,$object->error); - $action=''; - } - } -} - -if ($action == 'setsocid') -{ - $error=0; - if (! $error) - { - if ($socid != $object->fk_soc) // If link differs from currently in database - { - $sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql.=" WHERE fk_soc = '".$socid."'"; - $sql.=" AND entity = ".$conf->entity; - $resql = $db->query($sql); - if ($resql) + if ($userid != $user->id && $userid != $object->user_id) { - $obj = $db->fetch_object($resql); - if ($obj && $obj->rowid > 0) - { - $othermember=new Adherent($db); - $othermember->fetch($obj->rowid); - $thirdparty=new Societe($db); - $thirdparty->fetch($socid); - $error++; - $errmsg='
'.$langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name).'
'; - } + $error++; + $mesg='
'.$langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly").'
'; } + } - if (! $error) + if (! $error) + { + if ($userid != $object->user_id) // If link differs from currently in database { - $result=$object->setThirdPartyId($socid); + $result=$object->setUserId($userid); if ($result < 0) dol_print_error($object->db,$object->error); $action=''; } } } -} -// Create user from a member -if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer) -{ - if ($result > 0) + if ($action == 'setsocid') { - // Creation user - $nuser = new User($db); - $result=$nuser->create_from_member($object,GETPOST('login')); - - if ($result < 0) + $error=0; + if (! $error) { - $langs->load("errors"); - $errmsg=$langs->trans($nuser->error); - } - } - else - { - $errmsg=$object->error; - } -} - -// Create third party from a member -if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer) -{ - if ($result > 0) - { - // Creation user - $company = new Societe($db); - $result=$company->create_from_member($object,GETPOST('companyname')); - - if ($result < 0) - { - $langs->load("errors"); - $errmsg=$langs->trans($company->error); - $errmsgs=$company->errors; - } - } - else - { - $errmsg=$object->error; - } -} - -if ($action == 'confirm_sendinfo' && $confirm == 'yes') -{ - if ($object->email) - { - $from=$conf->email_from; - if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; - - $result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent")); - - $langs->load("mails"); - $mesg=$langs->trans("MailSuccessfulySent", $from, $object->email); - } -} - -if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $birthdate=''; - if (isset($_POST["birthday"]) && $_POST["birthday"] - && isset($_POST["birthmonth"]) && $_POST["birthmonth"] - && isset($_POST["birthyear"]) && $_POST["birthyear"]) - { - $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); - } - $lastname=$_POST["lastname"]; - $firstname=$_POST["firstname"]; - $morphy=$morphy=$_POST["morphy"];; - if ($morphy != 'mor' && empty($lastname)) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."
\n"; - } - if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."
\n"; - } - - // Create new object - if ($result > 0 && ! $error) - { - $object->oldcopy=dol_clone($object); - - // Change values - $object->civility_id = trim($_POST["civility_id"]); - $object->firstname = trim($_POST["firstname"]); - $object->lastname = trim($_POST["lastname"]); - $object->login = trim($_POST["login"]); - $object->pass = trim($_POST["pass"]); - - $object->societe = trim($_POST["societe"]); - $object->company = trim($_POST["societe"]); - - $object->address = trim($_POST["address"]); - $object->zip = trim($_POST["zipcode"]); - $object->town = trim($_POST["town"]); - $object->state_id = $_POST["state_id"]; - $object->country_id = $_POST["country_id"]; - - $object->phone = trim($_POST["phone"]); - $object->phone_perso = trim($_POST["phone_perso"]); - $object->phone_mobile= trim($_POST["phone_mobile"]); - $object->email = trim($_POST["email"]); - $object->skype = trim($_POST["skype"]); - $object->birth = $birthdate; - - $object->typeid = $_POST["typeid"]; - //$object->note = trim($_POST["comment"]); - $object->morphy = $_POST["morphy"]; - - $object->amount = $_POST["amount"]; - - if (GETPOST('deletephoto')) $object->photo=''; - elseif (! empty($_FILES['photo']['name'])) $object->photo = dol_sanitizeFileName($_FILES['photo']['name']); - - // Get status and public property - $object->statut = $_POST["statut"]; - $object->public = $_POST["public"]; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Check if we need to also synchronize user information - $nosyncuser=0; - if ($object->user_id) // If linked to a user - { - if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1; // Disable synchronizing - } - - // Check if we need to also synchronize password information - $nosyncuserpass=0; - if ($object->user_id) // If linked to a user - { - if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1; // Disable synchronizing - } - - $result=$object->update($user,0,$nosyncuser,$nosyncuserpass); - if ($result >= 0 && ! count($object->errors)) - { - // Logo/Photo save - $dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos'; - $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); - if ($file_OK) + if ($socid != $object->fk_soc) // If link differs from currently in database { - if (GETPOST('deletephoto')) + $sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; + $sql.=" WHERE fk_soc = '".$socid."'"; + $sql.=" AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo; - $dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs'; - dol_delete_file($fileimg); - dol_delete_dir_recursive($dirthumbs); + $obj = $db->fetch_object($resql); + if ($obj && $obj->rowid > 0) + { + $othermember=new Adherent($db); + $othermember->fetch($obj->rowid); + $thirdparty=new Societe($db); + $thirdparty->fetch($socid); + $error++; + $errmsg='
'.$langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name).'
'; + } } - if (image_format_supported($_FILES['photo']['name']) > 0) + if (! $error) { - dol_mkdir($dir); + $result=$object->setThirdPartyId($socid); + if ($result < 0) dol_print_error($object->db,$object->error); + $action=''; + } + } + } + } - if (@is_dir($dir)) + // Create user from a member + if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer) + { + if ($result > 0) + { + // Creation user + $nuser = new User($db); + $result=$nuser->create_from_member($object,GETPOST('login')); + + if ($result < 0) + { + $langs->load("errors"); + $errmsg=$langs->trans($nuser->error); + } + } + else + { + $errmsg=$object->error; + } + } + + // Create third party from a member + if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer) + { + if ($result > 0) + { + // Creation user + $company = new Societe($db); + $result=$company->create_from_member($object,GETPOST('companyname')); + + if ($result < 0) + { + $langs->load("errors"); + $errmsg=$langs->trans($company->error); + $errmsgs=$company->errors; + } + } + else + { + $errmsg=$object->error; + } + } + + if ($action == 'confirm_sendinfo' && $confirm == 'yes') + { + if ($object->email) + { + $from=$conf->email_from; + if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM; + + $result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent")); + + $langs->load("mails"); + $mesg=$langs->trans("MailSuccessfulySent", $from, $object->email); + } + } + + if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $birthdate=''; + if (isset($_POST["birthday"]) && $_POST["birthday"] + && isset($_POST["birthmonth"]) && $_POST["birthmonth"] + && isset($_POST["birthyear"]) && $_POST["birthyear"]) + { + $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); + } + $lastname=$_POST["lastname"]; + $firstname=$_POST["firstname"]; + $morphy=$morphy=$_POST["morphy"];; + if ($morphy != 'mor' && empty($lastname)) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."
\n"; + } + if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."
\n"; + } + + // Create new object + if ($result > 0 && ! $error) + { + $object->oldcopy=dol_clone($object); + + // Change values + $object->civility_id = trim($_POST["civility_id"]); + $object->firstname = trim($_POST["firstname"]); + $object->lastname = trim($_POST["lastname"]); + $object->login = trim($_POST["login"]); + $object->pass = trim($_POST["pass"]); + + $object->societe = trim($_POST["societe"]); + $object->company = trim($_POST["societe"]); + + $object->address = trim($_POST["address"]); + $object->zip = trim($_POST["zipcode"]); + $object->town = trim($_POST["town"]); + $object->state_id = $_POST["state_id"]; + $object->country_id = $_POST["country_id"]; + + $object->phone = trim($_POST["phone"]); + $object->phone_perso = trim($_POST["phone_perso"]); + $object->phone_mobile= trim($_POST["phone_mobile"]); + $object->email = trim($_POST["email"]); + $object->skype = trim($_POST["skype"]); + $object->birth = $birthdate; + + $object->typeid = $_POST["typeid"]; + //$object->note = trim($_POST["comment"]); + $object->morphy = $_POST["morphy"]; + + $object->amount = $_POST["amount"]; + + if (GETPOST('deletephoto')) $object->photo=''; + elseif (! empty($_FILES['photo']['name'])) $object->photo = dol_sanitizeFileName($_FILES['photo']['name']); + + // Get status and public property + $object->statut = $_POST["statut"]; + $object->public = $_POST["public"]; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Check if we need to also synchronize user information + $nosyncuser=0; + if ($object->user_id) // If linked to a user + { + if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1; // Disable synchronizing + } + + // Check if we need to also synchronize password information + $nosyncuserpass=0; + if ($object->user_id) // If linked to a user + { + if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1; // Disable synchronizing + } + + $result=$object->update($user,0,$nosyncuser,$nosyncuserpass); + if ($result >= 0 && ! count($object->errors)) + { + // Logo/Photo save + $dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos'; + $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); + if ($file_OK) + { + if (GETPOST('deletephoto')) { - $newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']); - if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0) - { - $message .= '
'.$langs->trans("ErrorFailedToSaveFile").'
'; - } - else - { - // Create small thumbs for company (Ratio is near 16/9) - // Used on logon for example - $imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality); + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo; + $dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs'; + dol_delete_file($fileimg); + dol_delete_dir_recursive($dirthumbs); + } - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality); + if (image_format_supported($_FILES['photo']['name']) > 0) + { + dol_mkdir($dir); + + if (@is_dir($dir)) + { + $newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']); + if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0) + { + $message .= '
'.$langs->trans("ErrorFailedToSaveFile").'
'; + } + else + { + // Create small thumbs for company (Ratio is near 16/9) + // Used on logon for example + $imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality); + + // Create mini thumbs for company (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality); + } } } + else + { + $errmsgs[] = "ErrorBadImageFormat"; + } } else { - $errmsgs[] = "ErrorBadImageFormat"; + switch($_FILES['photo']['error']) + { + case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini + case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form + $errors[] = "ErrorFileSizeTooLarge"; + break; + case 3: //uploaded file was only partially uploaded + $errors[] = "ErrorFilePartiallyUploaded"; + break; + } + } + + $rowid=$object->id; + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; } } else { - switch($_FILES['photo']['error']) - { - case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini - case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form - $errors[] = "ErrorFileSizeTooLarge"; - break; - case 3: //uploaded file was only partially uploaded - $errors[] = "ErrorFilePartiallyUploaded"; - break; + if ($object->error) $errmsg=$object->error; + else $errmsgs=$object->errors; + $action=''; + } + } + else + { + $action='edit'; + } + } + + if ($action == 'add' && $user->rights->adherent->creer) + { + if ($canvas) $object->canvas=$canvas; + $birthdate=''; + if (isset($_POST["birthday"]) && $_POST["birthday"] + && isset($_POST["birthmonth"]) && $_POST["birthmonth"] + && isset($_POST["birthyear"]) && $_POST["birthyear"]) + { + $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); + } + $datecotisation=''; + if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"])) + { + $datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); + } + + $typeid=$_POST["typeid"]; + $civility_id=$_POST["civility_id"]; + $lastname=$_POST["lastname"]; + $firstname=$_POST["firstname"]; + $societe=$_POST["societe"]; + $address=$_POST["address"]; + $zip=$_POST["zipcode"]; + $town=$_POST["town"]; + $state_id=$_POST["state_id"]; + $country_id=$_POST["country_id"]; + + $phone=$_POST["phone"]; + $phone_perso=$_POST["phone_perso"]; + $phone_mobile=$_POST["phone_mobile"]; + $skype=$_POST["member_skype"]; + $email=$_POST["member_email"]; + $login=$_POST["member_login"]; + $pass=$_POST["password"]; + $photo=$_POST["photo"]; + //$comment=$_POST["comment"]; + $morphy=$_POST["morphy"]; + $cotisation=$_POST["cotisation"]; + $public=$_POST["public"]; + + $userid=$_POST["userid"]; + $socid=$_POST["socid"]; + + $object->civility_id = $civility_id; + $object->firstname = $firstname; + $object->lastname = $lastname; + $object->societe = $societe; + $object->address = $address; + $object->zip = $zip; + $object->town = $town; + $object->state_id = $state_id; + $object->country_id = $country_id; + $object->phone = $phone; + $object->phone_perso = $phone_perso; + $object->phone_mobile= $phone_mobile; + $object->skype = $skype; + $object->email = $email; + $object->login = $login; + $object->pass = $pass; + $object->naiss = $birthdate; + $object->photo = $photo; + $object->typeid = $typeid; + //$object->note = $comment; + $object->morphy = $morphy; + $object->user_id = $userid; + $object->fk_soc = $socid; + $object->public = $public; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Check parameters + if (empty($morphy) || $morphy == "-1") { + $error++; + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature"))."
\n"; + } + // Test si le login existe deja + if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) + { + if (empty($login)) { + $error++; + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->trans("Login"))."
\n"; + } + else { + $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorLoginAlreadyExists",$login)."
\n"; } } + if (empty($pass)) { + $error++; + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Password"))."
\n"; + } + } + if ($morphy != 'mor' && empty($lastname)) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."
\n"; + } + if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."
\n"; + } + if (! ($typeid > 0)) { // Keep () before ! + $error++; + $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type"))."
\n"; + } + if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) { + $error++; + $langs->load("errors"); + $errmsg .= $langs->trans("ErrorBadEMail",$email)."
\n"; + } + $public=0; + if (isset($public)) $public=1; - $rowid=$object->id; - $action=''; + if (! $error) + { + $db->begin(); + // Email a peu pres correct et le login n'existe pas + $result=$object->create($user); + if ($result > 0) + { + $db->commit(); + $rowid=$object->id; + $action=''; + } + else + { + $db->rollback(); + + if ($object->error) $errmsg=$object->error; + else $errmsgs=$object->errors; + + $action = 'create'; + } + } + else { + $action = 'create'; + } + } + + if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') + { + $result=$object->delete($rowid); + if ($result > 0) + { if (! empty($backtopage)) { header("Location: ".$backtopage); exit; } + else + { + header("Location: liste.php"); + exit; + } } else { - if ($object->error) $errmsg=$object->error; - else $errmsgs=$object->errors; - $action=''; + $errmesg=$object->error; } } - else + + if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes') { - $action='edit'; - } -} + $error=0; -if ($action == 'add' && $user->rights->adherent->creer) -{ - if ($canvas) $object->canvas=$canvas; - $birthdate=''; - if (isset($_POST["birthday"]) && $_POST["birthday"] - && isset($_POST["birthmonth"]) && $_POST["birthmonth"] - && isset($_POST["birthyear"]) && $_POST["birthyear"]) - { - $birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]); - } - $datecotisation=''; - if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"])) - { - $datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); - } - - $typeid=$_POST["typeid"]; - $civility_id=$_POST["civility_id"]; - $lastname=$_POST["lastname"]; - $firstname=$_POST["firstname"]; - $societe=$_POST["societe"]; - $address=$_POST["address"]; - $zip=$_POST["zipcode"]; - $town=$_POST["town"]; - $state_id=$_POST["state_id"]; - $country_id=$_POST["country_id"]; - - $phone=$_POST["phone"]; - $phone_perso=$_POST["phone_perso"]; - $phone_mobile=$_POST["phone_mobile"]; - $skype=$_POST["member_skype"]; - $email=$_POST["member_email"]; - $login=$_POST["member_login"]; - $pass=$_POST["password"]; - $photo=$_POST["photo"]; - //$comment=$_POST["comment"]; - $morphy=$_POST["morphy"]; - $cotisation=$_POST["cotisation"]; - $public=$_POST["public"]; - - $userid=$_POST["userid"]; - $socid=$_POST["socid"]; - - $object->civility_id = $civility_id; - $object->firstname = $firstname; - $object->lastname = $lastname; - $object->societe = $societe; - $object->address = $address; - $object->zip = $zip; - $object->town = $town; - $object->state_id = $state_id; - $object->country_id = $country_id; - $object->phone = $phone; - $object->phone_perso = $phone_perso; - $object->phone_mobile= $phone_mobile; - $object->skype = $skype; - $object->email = $email; - $object->login = $login; - $object->pass = $pass; - $object->naiss = $birthdate; - $object->photo = $photo; - $object->typeid = $typeid; - //$object->note = $comment; - $object->morphy = $morphy; - $object->user_id = $userid; - $object->fk_soc = $socid; - $object->public = $public; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Check parameters - if (empty($morphy) || $morphy == "-1") { - $error++; - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature"))."
\n"; - } - // Test si le login existe deja - if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) - { - if (empty($login)) { - $error++; - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->trans("Login"))."
\n"; - } - else { - $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'"; - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - } - if ($num) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorLoginAlreadyExists",$login)."
\n"; - } - } - if (empty($pass)) { - $error++; - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Password"))."
\n"; - } - } - if ($morphy != 'mor' && empty($lastname)) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."
\n"; - } - if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."
\n"; - } - if (! ($typeid > 0)) { // Keep () before ! - $error++; - $errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type"))."
\n"; - } - if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) { - $error++; - $langs->load("errors"); - $errmsg .= $langs->trans("ErrorBadEMail",$email)."
\n"; - } - $public=0; - if (isset($public)) $public=1; - - if (! $error) - { $db->begin(); - // Email a peu pres correct et le login n'existe pas - $result=$object->create($user); - if ($result > 0) + $adht = new AdherentType($db); + $adht->fetch($object->typeid); + + $result=$object->validate($user); + + if ($result >= 0 && ! count($object->errors)) + { + // Send confirmation Email (selon param du type adherent sinon generique) + if ($object->email && GETPOST("send_mail")) + { + $result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2); + if ($result < 0) + { + $error++; + $errmsg.=$object->error; + } + } + } + else + { + $error++; + if ($object->error) $errmsg=$object->error; + else $errmsgs=$object->errors; + } + + if (! $error) { $db->commit(); - $rowid=$object->id; - $action=''; } else { $db->rollback(); - - if ($object->error) $errmsg=$object->error; - else $errmsgs=$object->errors; - - $action = 'create'; } + $action=''; } - else { - $action = 'create'; - } -} -if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') -{ - $result=$object->delete($rowid); - if ($result > 0) + if ($user->rights->adherent->supprimer && $action == 'confirm_resign') { - if (! empty($backtopage)) + if ($confirm == 'yes') + { + $adht = new AdherentType($db); + $adht->fetch($object->typeid); + + $result=$object->resiliate($user); + + if ($result >= 0 && ! count($object->errors)) + { + if ($object->email && GETPOST("send_mail")) + { + $result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1); + } + if ($result < 0) + { + $errmsg.=$object->error; + } + } + else + { + if ($object->error) $errmsg=$object->error; + else $errmsgs=$object->errors; + $action=''; + } + } + if (! empty($backtopage) && ! $errmsg) { header("Location: ".$backtopage); exit; } - else - { - header("Location: liste.php"); - exit; - } } - else + + // SPIP Management + if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes') { - $errmesg=$object->error; - } -} - -if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes') -{ - $error=0; - - $db->begin(); - - $adht = new AdherentType($db); - $adht->fetch($object->typeid); - - $result=$object->validate($user); - - if ($result >= 0 && ! count($object->errors)) - { - // Send confirmation Email (selon param du type adherent sinon generique) - if ($object->email && GETPOST("send_mail")) + if (! count($object->errors)) { - $result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2); - if ($result < 0) + if (!$mailmanspip->del_to_spip($object)) { - $error++; - $errmsg.=$object->error; + $errmsg.= $langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error."
\n"; } } } - else - { - $error++; - if ($object->error) $errmsg=$object->error; - else $errmsgs=$object->errors; - } - if (! $error) + if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes') { - $db->commit(); - } - else - { - $db->rollback(); - } - $action=''; -} - -if ($user->rights->adherent->supprimer && $action == 'confirm_resign') -{ - if ($confirm == 'yes') - { - $adht = new AdherentType($db); - $adht->fetch($object->typeid); - - $result=$object->resiliate($user); - - if ($result >= 0 && ! count($object->errors)) + if (! count($object->errors)) { - if ($object->email && GETPOST("send_mail")) + if (!$mailmanspip->add_to_spip($object)) { - $result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1); - } - if ($result < 0) - { - $errmsg.=$object->error; + $errmsg.= $langs->trans('AddIntoSpipError').': '.$mailmanspip->error."
\n"; } } - else - { - if ($object->error) $errmsg=$object->error; - else $errmsgs=$object->errors; - $action=''; - } - } - if (! empty($backtopage) && ! $errmsg) - { - header("Location: ".$backtopage); - exit; } } -// SPIP Management -if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes') -{ - if (! count($object->errors)) - { - if (!$mailmanspip->del_to_spip($object)) - { - $errmsg.= $langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error."
\n"; - } - } -} - -if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes') -{ - if (! count($object->errors)) - { - if (!$mailmanspip->add_to_spip($object)) - { - $errmsg.= $langs->trans('AddIntoSpipError').': '.$mailmanspip->error."
\n"; - } - } -} - - /* * View diff --git a/htdocs/comm/fiche.php b/htdocs/comm/fiche.php index 307a8c57385..0741b468ed9 100644 --- a/htdocs/comm/fiche.php +++ b/htdocs/comm/fiche.php @@ -79,76 +79,78 @@ $object = new Societe($db); $parameters = array('socid' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some -//Some actions show a "cancel" input submit button with name="cancel" -$cancelbutton = GETPOST('cancel'); +if (empty($reshook)) { + //Some actions show a "cancel" input submit button with name="cancel" + $cancelbutton = GETPOST('cancel'); -if ($action == 'setcustomeraccountancycode') -{ - if (!$cancelbutton) { - $result=$object->fetch($id); - $object->code_compta=$_POST["customeraccountancycode"]; - $result=$object->update($object->id,$user,1,1,0); - if ($result < 0) - { - $mesgs[]=join(',',$object->errors); + if ($action == 'setcustomeraccountancycode') + { + if (!$cancelbutton) { + $result=$object->fetch($id); + $object->code_compta=$_POST["customeraccountancycode"]; + $result=$object->update($object->id,$user,1,1,0); + if ($result < 0) + { + $mesgs[]=join(',',$object->errors); + } + $action=""; } - $action=""; } -} -// conditions de reglement -if ($action == 'setconditions' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} -// mode de reglement -if ($action == 'setmode' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} -// assujetissement a la TVA -if ($action == 'setassujtva' && $user->rights->societe->creer) -{ - $object->fetch($id); - $object->tva_assuj=$_POST['assujtva_value']; - - // TODO move to DAO class - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET tva_assuj='".$_POST['assujtva_value']."' WHERE rowid='".$id."'"; - $result = $db->query($sql); - if (! $result) dol_print_error($result); -} - -// set prospect level -if ($action == 'setprospectlevel' && $user->rights->societe->creer) -{ - $object->fetch($id); - $object->fk_prospectlevel=GETPOST('prospect_level_id','alpha'); - $result=$object->set_prospect_level($user); - if ($result < 0) setEventMessage($object->error,'errors'); -} - -// Update communication level -if ($action == 'cstc') -{ - $object->fetch($id); - $object->stcomm_id=GETPOST('stcomm','int'); - $result=$object->set_commnucation_level($user); - if ($result < 0) setEventMessage($object->error,'errors'); -} - -// Update communication level -if ($action == 'setOutstandingBill') -{ - if (!$cancelbutton) { + // conditions de reglement + if ($action == 'setconditions' && $user->rights->societe->creer) + { $object->fetch($id); - $object->outstanding_limit = GETPOST('OutstandingBill'); - $result = $object->set_OutstandingBill($user); - if ($result < 0) { - setEventMessage($object->error, 'errors'); + $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + // mode de reglement + if ($action == 'setmode' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + // assujetissement a la TVA + if ($action == 'setassujtva' && $user->rights->societe->creer) + { + $object->fetch($id); + $object->tva_assuj=$_POST['assujtva_value']; + + // TODO move to DAO class + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET tva_assuj='".$_POST['assujtva_value']."' WHERE rowid='".$id."'"; + $result = $db->query($sql); + if (! $result) dol_print_error($result); + } + + // set prospect level + if ($action == 'setprospectlevel' && $user->rights->societe->creer) + { + $object->fetch($id); + $object->fk_prospectlevel=GETPOST('prospect_level_id','alpha'); + $result=$object->set_prospect_level($user); + if ($result < 0) setEventMessage($object->error,'errors'); + } + + // Update communication level + if ($action == 'cstc') + { + $object->fetch($id); + $object->stcomm_id=GETPOST('stcomm','int'); + $result=$object->set_commnucation_level($user); + if ($result < 0) setEventMessage($object->error,'errors'); + } + + // Update communication level + if ($action == 'setOutstandingBill') + { + if (!$cancelbutton) { + $object->fetch($id); + $object->outstanding_limit = GETPOST('OutstandingBill'); + $result = $object->set_OutstandingBill($user); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } } } } diff --git a/htdocs/comm/mailing/fiche.php b/htdocs/comm/mailing/fiche.php index d803de28357..6e7546fb70d 100644 --- a/htdocs/comm/mailing/fiche.php +++ b/htdocs/comm/mailing/fiche.php @@ -102,446 +102,390 @@ $object->substitutionarrayfortest=array( $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes') -{ - if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) +if (empty($reshook)) { + + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes') { - $mesg='
'.$langs->trans("NoCloneOptionsSpecified").'
'; - } - else - { - $result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]); - if ($result > 0) + if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); - exit; + $mesg='
'.$langs->trans("NoCloneOptionsSpecified").'
'; } else { - $mesg=$object->error; - } - } - $action=''; -} - -// Action send emailing for everybody -if ($action == 'sendallconfirmed' && $confirm == 'yes') -{ - if (empty($conf->global->MAILING_LIMIT_SENDBYWEB)) - { - // Pour des raisons de securite, on ne permet pas cette fonction via l'IHM, - // on affiche donc juste un message - $mesg='
'.$langs->trans("MailingNeedCommand").'
'; - $mesg.='
'; - $mesg.='

'.$langs->trans("MailingNeedCommand2").'
'; - $action=''; - } - else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0) - { - $mesg='
'.$langs->trans("NotEnoughPermissions").'
'; - $action=''; - } - else - { - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - if ($object->statut == 0) - { - dol_print_error('','ErrorMailIsNotValidated'); - exit; - } - - $id = $object->id; - $subject = $object->sujet; - $message = $object->body; - $from = $object->email_from; - $replyto = $object->email_replyto; - $errorsto = $object->email_errorsto; - // Le message est-il en html - $msgishtml=-1; // Unknown by default - if (preg_match('/[\s\t]*/i',$message)) $msgishtml=1; - - // Warning, we must not use begin-commit transaction here - // because we want to save update for each mail sent. - - $nbok=0; $nbko=0; - - // On choisit les mails non deja envoyes pour ce mailing (statut=0) - // ou envoyes en erreur (statut=-1) - $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag"; - $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; - $sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id; - - dol_syslog("fiche.php: select targets sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); // nb of possible recipients - - if ($num) + $result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]); + if ($result > 0) { - dol_syslog("comm/mailing/fiche.php: nb of targets = ".$num, LOG_DEBUG); + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + exit; + } + else + { + $mesg=$object->error; + } + } + $action=''; + } - $now=dol_now(); + // Action send emailing for everybody + if ($action == 'sendallconfirmed' && $confirm == 'yes') + { + if (empty($conf->global->MAILING_LIMIT_SENDBYWEB)) + { + // Pour des raisons de securite, on ne permet pas cette fonction via l'IHM, + // on affiche donc juste un message + $mesg='
'.$langs->trans("MailingNeedCommand").'
'; + $mesg.='
'; + $mesg.='

'.$langs->trans("MailingNeedCommand2").'
'; + $action=''; + } + else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0) + { + $mesg='
'.$langs->trans("NotEnoughPermissions").'
'; + $action=''; + } + else + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - // Positionne date debut envoi - $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id; + if ($object->statut == 0) + { + dol_print_error('','ErrorMailIsNotValidated'); + exit; + } + + $id = $object->id; + $subject = $object->sujet; + $message = $object->body; + $from = $object->email_from; + $replyto = $object->email_replyto; + $errorsto = $object->email_errorsto; + // Le message est-il en html + $msgishtml=-1; // Unknown by default + if (preg_match('/[\s\t]*/i',$message)) $msgishtml=1; + + // Warning, we must not use begin-commit transaction here + // because we want to save update for each mail sent. + + $nbok=0; $nbko=0; + + // On choisit les mails non deja envoyes pour ce mailing (statut=0) + // ou envoyes en erreur (statut=-1) + $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag"; + $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; + $sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id; + + dol_syslog("fiche.php: select targets sql=".$sql, LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); // nb of possible recipients + + if ($num) + { + dol_syslog("comm/mailing/fiche.php: nb of targets = ".$num, LOG_DEBUG); + + $now=dol_now(); + + // Positionne date debut envoi + $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + + // Loop on each email and send it + $i = 0; + + while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB) + { + + $res=1; + + $obj = $db->fetch_object($resql); + + // sendto en RFC2822 + $sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">"; + + // Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ... + $other=explode(';',$obj->other); + $tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions) + $substitutionarray=array( + '__ID__' => $obj->source_id, + '__EMAIL__' => $obj->email, + '__LASTNAME__' => $obj->lastname, + '__FIRSTNAME__' => $obj->firstname, + '__MAILTOEMAIL__' => ''.$obj->email.'', + '__OTHER1__' => $other1, + '__OTHER2__' => $other2, + '__OTHER3__' => $other3, + '__OTHER4__' => $other4, + '__OTHER5__' => $other5, + '__CHECK_READ__' => '', + '__UNSUBSCRIBE__' => ''.$langs->trans("MailUnsubcribe").'' + ); + if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) + { + $substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); + if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); + else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); + } + $substitutionisok=true; + complete_substitutions_array($substitutionarray, $langs); + $newsubject=make_substitutions($subject,$substitutionarray); + $newmessage=make_substitutions($message,$substitutionarray); + + $arr_file = array(); + $arr_mime = array(); + $arr_name = array(); + $arr_css = array(); + + $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); + if (count($listofpaths)) + { + foreach($listofpaths as $key => $val) + { + $arr_file[]=$listofpaths[$key]['fullname']; + $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); + $arr_name[]=$listofpaths[$key]['name']; + } + } + + // Fabrication du mail + $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css); + + if ($mail->error) + { + $res=0; + } + if (! $substitutionisok) + { + $mail->error='Some substitution failed'; + $res=0; + } + + // Send mail + if ($res) + { + $res=$mail->sendfile(); + } + + if ($res) + { + // Mail successful + $nbok++; + + dol_syslog("comm/mailing/fiche.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG); + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; + $sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + else + { + //if cheack read is use then update prospect contact status + if (strpos($message, '__CHECK_READ__') !== false) + { + //Update status communication of thirdparty prospect + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")"; + dol_syslog("fiche.php: set prospect thirdparty status sql=".$sql, LOG_DEBUG); + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + + //Update status communication of contact prospect + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)"; + dol_syslog("fiche.php: set prospect contact status sql=".$sql, LOG_DEBUG); + + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + } + } + + + //test if CHECK READ change statut prospect contact + } + else + { + // Mail failed + $nbko++; + + dol_syslog("comm/mailing/fiche.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING); + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; + $sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; + $resql2=$db->query($sql); + if (! $resql2) + { + dol_print_error($db); + } + } + + $i++; + } + } + else + { + setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo")); + } + + // Loop finished, set global statut of mail + if ($nbko > 0) + { + $statut=2; // Status 'sent partially' (because at least one error) + if ($nbok > 0) setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + else + { + if ($nbok >= $num) + { + $statut=3; // Send to everybody + setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + else + { + $statut=2; // Status 'sent partially' (because not send to everybody) + setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); + } + } + + $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id; + dol_syslog("comm/mailing/fiche.php: update global status sql=".$sql, LOG_DEBUG); $resql2=$db->query($sql); if (! $resql2) { dol_print_error($db); } - - // Loop on each email and send it - $i = 0; - - while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB) - { - - $res=1; - - $obj = $db->fetch_object($resql); - - // sendto en RFC2822 - $sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">"; - - // Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ... - $other=explode(';',$obj->other); - $tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); - // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions) - $substitutionarray=array( - '__ID__' => $obj->source_id, - '__EMAIL__' => $obj->email, - '__LASTNAME__' => $obj->lastname, - '__FIRSTNAME__' => $obj->firstname, - '__MAILTOEMAIL__' => ''.$obj->email.'', - '__OTHER1__' => $other1, - '__OTHER2__' => $other2, - '__OTHER3__' => $other3, - '__OTHER4__' => $other4, - '__OTHER5__' => $other5, - '__CHECK_READ__' => '', - '__UNSUBSCRIBE__' => ''.$langs->trans("MailUnsubcribe").'' - ); - if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) - { - $substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); - if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); - } - $substitutionisok=true; - complete_substitutions_array($substitutionarray, $langs); - $newsubject=make_substitutions($subject,$substitutionarray); - $newmessage=make_substitutions($message,$substitutionarray); - - $arr_file = array(); - $arr_mime = array(); - $arr_name = array(); - $arr_css = array(); - - $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); - if (count($listofpaths)) - { - foreach($listofpaths as $key => $val) - { - $arr_file[]=$listofpaths[$key]['fullname']; - $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); - $arr_name[]=$listofpaths[$key]['name']; - } - } - - // Fabrication du mail - $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css); - - if ($mail->error) - { - $res=0; - } - if (! $substitutionisok) - { - $mail->error='Some substitution failed'; - $res=0; - } - - // Send mail - if ($res) - { - $res=$mail->sendfile(); - } - - if ($res) - { - // Mail successful - $nbok++; - - dol_syslog("comm/mailing/fiche.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG); - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; - $sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - else - { - //if cheack read is use then update prospect contact status - if (strpos($message, '__CHECK_READ__') !== false) - { - //Update status communication of thirdparty prospect - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")"; - dol_syslog("fiche.php: set prospect thirdparty status sql=".$sql, LOG_DEBUG); - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - - //Update status communication of contact prospect - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)"; - dol_syslog("fiche.php: set prospect contact status sql=".$sql, LOG_DEBUG); - - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - } - } - - - //test if CHECK READ change statut prospect contact - } - else - { - // Mail failed - $nbko++; - - dol_syslog("comm/mailing/fiche.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING); - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; - $sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid; - $resql2=$db->query($sql); - if (! $resql2) - { - dol_print_error($db); - } - } - - $i++; - } } else { - setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo")); - } - - // Loop finished, set global statut of mail - if ($nbko > 0) - { - $statut=2; // Status 'sent partially' (because at least one error) - if ($nbok > 0) setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - else - { - if ($nbok >= $num) - { - $statut=3; // Send to everybody - setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - else - { - $statut=2; // Status 'sent partially' (because not send to everybody) - setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok)); - } - } - - $sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id; - dol_syslog("comm/mailing/fiche.php: update global status sql=".$sql, LOG_DEBUG); - $resql2=$db->query($sql); - if (! $resql2) - { + dol_syslog($db->error()); dol_print_error($db); } + + $action = ''; } - else - { - dol_syslog($db->error()); - dol_print_error($db); - } - - $action = ''; - } -} - -// Action send test emailing -if ($action == 'send' && empty($_POST["cancel"])) -{ - $error=0; - - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - $object->sendto = $_POST["sendto"]; - if (! $object->sendto) - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->trans("MailTo")).'
'; - $error++; } - if (! $error) + // Action send test emailing + if ($action == 'send' && empty($_POST["cancel"])) { - // Le message est-il en html - $msgishtml=-1; // Inconnu par defaut - if (preg_match('/[\s\t]*/i',$object->body)) $msgishtml=1; + $error=0; - // Pratique les substitutions sur le sujet et message - $tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest); - $tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest); + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - $arr_file = array(); - $arr_mime = array(); - $arr_name = array(); - $arr_css = array(); - - // Ajout CSS - if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor; - if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage; - - // Attached files - $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); - if (count($listofpaths)) + $object->sendto = $_POST["sendto"]; + if (! $object->sendto) { - foreach($listofpaths as $key => $val) + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->trans("MailTo")).'
'; + $error++; + } + + if (! $error) + { + // Le message est-il en html + $msgishtml=-1; // Inconnu par defaut + if (preg_match('/[\s\t]*/i',$object->body)) $msgishtml=1; + + // Pratique les substitutions sur le sujet et message + $tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest); + $tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest); + + $arr_file = array(); + $arr_mime = array(); + $arr_name = array(); + $arr_css = array(); + + // Ajout CSS + if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor; + if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage; + + // Attached files + $listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0); + if (count($listofpaths)) { - $arr_file[]=$listofpaths[$key]['fullname']; - $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); - $arr_name[]=$listofpaths[$key]['name']; + foreach($listofpaths as $key => $val) + { + $arr_file[]=$listofpaths[$key]['fullname']; + $arr_mime[]=dol_mimetype($listofpaths[$key]['name']); + $arr_name[]=$listofpaths[$key]['name']; + } } + + $mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css); + + $result=$mailfile->sendfile(); + if ($result) + { + $mesg='
'.$langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)).'
'; + } + else + { + $mesg='
'.$langs->trans("ResultKo").'
'.$mailfile->error.' '.$result.'
'; + } + + $action=''; } - - $mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css); - - $result=$mailfile->sendfile(); - if ($result) - { - $mesg='
'.$langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)).'
'; - } - else - { - $mesg='
'.$langs->trans("ResultKo").'
'.$mailfile->error.' '.$result.'
'; - } - - $action=''; - } -} - -// Action add emailing -if ($action == 'add') -{ - $object->email_from = trim($_POST["from"]); - $object->email_replyto = trim($_POST["replyto"]); - $object->email_errorsto = trim($_POST["errorsto"]); - $object->titre = trim($_POST["titre"]); - $object->sujet = trim($_POST["sujet"]); - $object->body = trim($_POST["body"]); - $object->bgcolor = trim($_POST["bgcolor"]); - $object->bgimage = trim($_POST["bgimage"]); - - if (! $object->titre) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); - if (! $object->sujet) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); - if (! $object->body) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); - - if (! $mesg) - { - if ($object->create($user) >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - $mesg=$object->error; } - $mesg='
'.$mesg.'
'; - $action="create"; -} - -// Action update description of emailing -if ($action == 'settitre' || $action == 'setemail_from' || $actino == 'setreplyto' || $action == 'setemail_errorsto') -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - if ($action == 'settitre') $object->titre = trim(GETPOST('titre','alpha')); - else if ($action == 'setemail_from') $object->email_from = trim(GETPOST('email_from','alpha')); - else if ($action == 'setemail_replyto') $object->email_replyto = trim(GETPOST('email_replyto','alpha')); - else if ($action == 'setemail_errorsto') $object->email_errorsto = trim(GETPOST('email_errorsto','alpha')); - - else if ($action == 'settitre' && empty($object->titre)) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); - else if ($action == 'setfrom' && empty($object->email_from)) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom")); - - if (! $mesg) - { - if ($object->update($user) >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - $mesg=$object->error; - } - - $mesg='
'.$mesg.'
'; - $action=""; -} - -/* - * Add file in email form - */ -if (! empty($_POST['addfile'])) -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory - dol_add_file_process($upload_dir,0,0); - - $action="edit"; -} - -// Action remove file -if (! empty($_POST["removedfile"])) -{ - $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - dol_remove_file_process($_POST['removedfile'],0); - - $action="edit"; -} - -// Action update emailing -if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"])) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $isupload=0; - - if (! $isupload) + // Action add emailing + if ($action == 'add') { + $object->email_from = trim($_POST["from"]); + $object->email_replyto = trim($_POST["replyto"]); + $object->email_errorsto = trim($_POST["errorsto"]); + $object->titre = trim($_POST["titre"]); $object->sujet = trim($_POST["sujet"]); $object->body = trim($_POST["body"]); $object->bgcolor = trim($_POST["bgcolor"]); $object->bgimage = trim($_POST["bgimage"]); + if (! $object->titre) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); if (! $object->sujet) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); if (! $object->body) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); + if (! $mesg) + { + if ($object->create($user) >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + $mesg=$object->error; + } + + $mesg='
'.$mesg.'
'; + $action="create"; + } + + // Action update description of emailing + if ($action == 'settitre' || $action == 'setemail_from' || $actino == 'setreplyto' || $action == 'setemail_errorsto') + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + if ($action == 'settitre') $object->titre = trim(GETPOST('titre','alpha')); + else if ($action == 'setemail_from') $object->email_from = trim(GETPOST('email_from','alpha')); + else if ($action == 'setemail_replyto') $object->email_replyto = trim(GETPOST('email_replyto','alpha')); + else if ($action == 'setemail_errorsto') $object->email_errorsto = trim(GETPOST('email_errorsto','alpha')); + + else if ($action == 'settitre' && empty($object->titre)) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle")); + else if ($action == 'setfrom' && empty($object->email_from)) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom")); + if (! $mesg) { if ($object->update($user) >= 0) @@ -553,78 +497,136 @@ if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel" } $mesg='
'.$mesg.'
'; + $action=""; + } + + /* + * Add file in email form + */ + if (! empty($_POST['addfile'])) + { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + dol_add_file_process($upload_dir,0,0); + $action="edit"; } - else + + // Action remove file + if (! empty($_POST["removedfile"])) { + $upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1); + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + dol_remove_file_process($_POST['removedfile'],0); + $action="edit"; } -} -// Action confirmation validation -if ($action == 'confirm_valid' && $confirm == 'yes') -{ - if ($object->id > 0) + // Action update emailing + if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"])) { - $object->valid($user); - setEventMessage($langs->trans("MailingSuccessfullyValidated")); - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - dol_print_error($db); - } -} + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -// Resend -if ($action == 'confirm_reset' && $confirm == 'yes') -{ - if ($object->id > 0) - { - $db->begin(); + $isupload=0; - $result=$object->valid($user); - if ($result > 0) + if (! $isupload) { - $result=$object->reset_targets_status($user); + $object->sujet = trim($_POST["sujet"]); + $object->body = trim($_POST["body"]); + $object->bgcolor = trim($_POST["bgcolor"]); + $object->bgimage = trim($_POST["bgimage"]); + + if (! $object->sujet) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic")); + if (! $object->body) $mesg.=($mesg?'
':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage")); + + if (! $mesg) + { + if ($object->update($user) >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + $mesg=$object->error; + } + + $mesg='
'.$mesg.'
'; + $action="edit"; } - - if ($result > 0) + else { - $db->commit(); + $action="edit"; + } + } + + // Action confirmation validation + if ($action == 'confirm_valid' && $confirm == 'yes') + { + if ($object->id > 0) + { + $object->valid($user); + setEventMessage($langs->trans("MailingSuccessfullyValidated")); header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } else { - $mesg=$object->error; - $db->rollback(); + dol_print_error($db); } } - else + + // Resend + if ($action == 'confirm_reset' && $confirm == 'yes') { - dol_print_error($db); + if ($object->id > 0) + { + $db->begin(); + + $result=$object->valid($user); + if ($result > 0) + { + $result=$object->reset_targets_status($user); + } + + if ($result > 0) + { + $db->commit(); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + $mesg=$object->error; + $db->rollback(); + } + } + else + { + dol_print_error($db); + } + } + + // Action confirmation suppression + if ($action == 'confirm_delete' && $confirm == 'yes') + { + if ($object->delete($object->id)) + { + $url= (! empty($urlfrom) ? $urlfrom : 'liste.php'); + header("Location: ".$url); + exit; + } + } + + if (! empty($_POST["cancel"])) + { + $action = ''; } } -// Action confirmation suppression -if ($action == 'confirm_delete' && $confirm == 'yes') -{ - if ($object->delete($object->id)) - { - $url= (! empty($urlfrom) ? $urlfrom : 'liste.php'); - header("Location: ".$url); - exit; - } -} - -if (! empty($_POST["cancel"])) -{ - $action = ''; -} - - /* * View diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 4929ee9c70e..945f6498ce5 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -106,65 +106,46 @@ $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some // hooks -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes') { - if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); - } else { - if ($object->id > 0) { - $result = $object->createFromClone($socid); - if ($result > 0) { - header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); - exit(); - } else { - setEventMessage($object->error, 'errors'); - $action = ''; + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes') { + if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) { + setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + } else { + if ($object->id > 0) { + $result = $object->createFromClone($socid); + if ($result > 0) { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); + exit(); + } else { + setEventMessage($object->error, 'errors'); + $action = ''; + } } } } -} -// Delete proposal -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) { - $result = $object->delete($user); - if ($result > 0) { - header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php'); - exit(); - } else { - $langs->load("errors"); - setEventMessage($langs->trans($object->error), 'errors'); - } -} - -// Remove line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) { - $result = $object->deleteline($lineid); - // reorder lines - if ($result) - $object->line_order(true); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); + // Delete proposal + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) { + $result = $object->delete($user); + if ($result > 0) { + header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php'); + exit(); + } else { + $langs->load("errors"); + setEventMessage($langs->trans($object->error), 'errors'); } - $ret = $object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); - exit(); -} + // Remove line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) { + $result = $object->deleteline($lineid); + // reorder lines + if ($result) + $object->line_order(true); -// Validation -else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) { - $result = $object->valid($user); - if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language $outputlangs = $langs; @@ -176,148 +157,587 @@ else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->pr $ret = $object->fetch($id); // Reload to get new records propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - } else { - $langs->load("errors"); - if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); - else setEventMessage($langs->trans($object->error), 'errors'); - } -} -else if ($action == 'setdate' && $user->rights->propal->creer) { - $datep = dol_mktime(12, 0, 0, $_POST ['remonth'], $_POST ['reday'], $_POST ['reyear']); - - if (empty($datep)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); } - if (! $error) { - $result = $object->set_date($user, $datep); + // Validation + else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) { + $result = $object->valid($user); + if ($result >= 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } else { + $langs->load("errors"); + if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans($object->error), 'errors'); + } + } + + else if ($action == 'setdate' && $user->rights->propal->creer) { + $datep = dol_mktime(12, 0, 0, $_POST ['remonth'], $_POST ['reday'], $_POST ['reyear']); + + if (empty($datep)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); + } + + if (! $error) { + $result = $object->set_date($user, $datep); + if ($result < 0) + dol_print_error($db, $object->error); + } + } else if ($action == 'setecheance' && $user->rights->propal->creer) { + $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST ['echmonth'], $_POST ['echday'], $_POST ['echyear'])); + if ($result < 0) + dol_print_error($db, $object->error); + } else if ($action == 'setdate_livraison' && $user->rights->propal->creer) { + $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST ['liv_month'], $_POST ['liv_day'], $_POST ['liv_year'])); if ($result < 0) dol_print_error($db, $object->error); } -} else if ($action == 'setecheance' && $user->rights->propal->creer) { - $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST ['echmonth'], $_POST ['echday'], $_POST ['echyear'])); - if ($result < 0) - dol_print_error($db, $object->error); -} else if ($action == 'setdate_livraison' && $user->rights->propal->creer) { - $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST ['liv_month'], $_POST ['liv_day'], $_POST ['liv_year'])); - if ($result < 0) - dol_print_error($db, $object->error); -} -// Positionne ref client -else if ($action == 'set_ref_client' && $user->rights->propal->creer) { - $object->set_ref_client($user, $_POST ['ref_client']); -} - -// Create proposal -else if ($action == 'add' && $user->rights->propal->creer) { - $object->socid = $socid; - $object->fetch_thirdparty(); - - $datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); - $duration = GETPOST('duree_validite'); - - if (empty($datep)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); - $action = 'create'; - $error ++; - } - if (empty($duration)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); - $action = 'create'; - $error ++; + // Positionne ref client + else if ($action == 'set_ref_client' && $user->rights->propal->creer) { + $object->set_ref_client($user, $_POST ['ref_client']); } - if ($socid < 1) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - $action = 'create'; - $error ++; - } + // Create proposal + else if ($action == 'add' && $user->rights->propal->creer) { + $object->socid = $socid; + $object->fetch_thirdparty(); - if (! $error) { - $db->begin(); + $datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + $duration = GETPOST('duree_validite'); - // Si on a selectionne une propal a copier, on realise la copie - if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) { - if ($object->fetch(GETPOST('copie_propal')) > 0) { + if (empty($datep)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors'); + $action = 'create'; + $error ++; + } + if (empty($duration)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); + $action = 'create'; + $error ++; + } + + if ($socid < 1) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + $action = 'create'; + $error ++; + } + + if (! $error) { + $db->begin(); + + // Si on a selectionne une propal a copier, on realise la copie + if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) { + if ($object->fetch(GETPOST('copie_propal')) > 0) { + $object->ref = GETPOST('ref'); + $object->datep = $datep; + $object->date_livraison = $date_delivery; + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->fk_delivery_address = GETPOST('fk_address'); + $object->duree_validite = $duration; + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->remise_percent = GETPOST('remise_percent'); + $object->remise_absolue = GETPOST('remise_absolue'); + $object->socid = GETPOST('socid'); + $object->contactid = GETPOST('contactidp'); + $object->fk_project = GETPOST('projectid'); + $object->modelpdf = GETPOST('model'); + $object->author = $user->id; // deprecated + $object->note = GETPOST('note'); + $object->statut = 0; + + $id = $object->create_from($user); + } else { + setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors'); + } + } else { $object->ref = GETPOST('ref'); + $object->ref_client = GETPOST('ref_client'); $object->datep = $datep; $object->date_livraison = $date_delivery; $object->availability_id = GETPOST('availability_id'); $object->demand_reason_id = GETPOST('demand_reason_id'); $object->fk_delivery_address = GETPOST('fk_address'); - $object->duree_validite = $duration; + $object->duree_validite = GETPOST('duree_validite'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->remise_percent = GETPOST('remise_percent'); - $object->remise_absolue = GETPOST('remise_absolue'); - $object->socid = GETPOST('socid'); + $object->contactid = GETPOST('contactidp'); $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated $object->note = GETPOST('note'); - $object->statut = 0; - $id = $object->create_from($user); - } else { - setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors'); - } - } else { - $object->ref = GETPOST('ref'); - $object->ref_client = GETPOST('ref_client'); - $object->datep = $datep; - $object->date_livraison = $date_delivery; - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->fk_delivery_address = GETPOST('fk_address'); - $object->duree_validite = GETPOST('duree_validite'); - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->origin = GETPOST('origin'); + $object->origin_id = GETPOST('originid'); - $object->contactid = GETPOST('contactidp'); - $object->fk_project = GETPOST('projectid'); - $object->modelpdf = GETPOST('model'); - $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); - - $object->origin = GETPOST('origin'); - $object->origin_id = GETPOST('originid'); - - for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) { - if ($_POST ['idprod' . $i]) { - $xid = 'idprod' . $i; - $xqty = 'qty' . $i; - $xremise = 'remise' . $i; - $object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]); - } - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error ++; - $action = 'create'; - } - } - - if (! $error) { - $id = $object->create($user); - - if ($id > 0) { - // Insertion contact par defaut si defini - if (GETPOST('contactidp') > 0) { - $result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external'); - if ($result < 0) { - $error ++; - setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) { + if ($_POST ['idprod' . $i]) { + $xid = 'idprod' . $i; + $xqty = 'qty' . $i; + $xremise = 'remise' . $i; + $object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]); } } - if (! $error) { + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + } + + if (! $error) { + $id = $object->create($user); + + if ($id > 0) { + // Insertion contact par defaut si defini + if (GETPOST('contactidp') > 0) { + $result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external'); + if ($result < 0) { + $error ++; + setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + } + } + + if (! $error) { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit(); + } else { + $db->rollback(); + } + } else { + dol_print_error($db, $object->error); + $db->rollback(); + exit(); + } + } + } + } + + // Classify billed + else if ($action == 'classifybilled' && $user->rights->propal->cloturer) { + $object->cloture($user, 4, ''); + } + + // Reopen proposal + else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + // prevent browser refresh from reopening proposal several times + if ($object->statut == 2 || $object->statut == 3) { + $object->reopen($user, 1); + } + } + + // Close proposal + else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { + if (! GETPOST('statut')) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors'); + $action = 'statut'; + } else { + // prevent browser refresh from closing proposal several times + if ($object->statut == 1) { + $object->cloture($user, GETPOST('statut'), GETPOST('note')); + } + } + } + + // Add file in email form + if (GETPOST('addfile')) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + // Set tmp user directory TODO Use a dedicated directory for temp mails files + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; + + dol_add_file_process($upload_dir_tmp, 0, 0); + $action = 'presend'; + } + + // Remove file in email form + if (GETPOST('removedfile')) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; + + // TODO Delete only files that was uploaded from email form + dol_remove_file_process($_POST ['removedfile'], 0); + $action = 'presend'; + } + + /* + * Send mail + */ + if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) { + $langs->load('mails'); + + if ($object->id > 0) { + if ($_POST ['sendto']) { + // Le destinataire a ete fourni via le champ libre + $sendto = $_POST ['sendto']; + $sendtoid = 0; + } elseif ($_POST ['receiver'] != '-1') { + // Recipient was provided from combo list + if ($_POST ['receiver'] == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } else // Id du contact + { + $sendto = $object->client->contact_get_property($_POST ['receiver'], 'email'); + $sendtoid = $_POST ['receiver']; + } + } + + if (dol_strlen($sendto)) { + $langs->load("commercial"); + + $from = $_POST ['fromname'] . ' <' . $_POST ['frommail'] . '>'; + $replyto = $_POST ['replytoname'] . ' <' . $_POST ['replytomail'] . '>'; + $message = $_POST ['message']; + $sendtocc = $_POST ['sendtocc']; + $deliveryreceipt = $_POST ['deliveryreceipt']; + + if (dol_strlen($_POST ['subject'])) + $subject = $_POST ['subject']; + else + $subject = $langs->transnoentities('Propal') . ' ' . $object->ref; + $actiontypecode = 'AC_PROP'; + $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; + if ($message) { + $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; + $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; + $actionmsg .= $message; + } + $actionmsg2 = $langs->transnoentities('Action' . $actiontypecode); + + // Create form object + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles = $formmail->get_attached_files(); + $filepath = $attachedfiles ['paths']; + $filename = $attachedfiles ['names']; + $mimetype = $attachedfiles ['mimes']; + + // Envoi de la propal + require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); + if ($mailfile->error) { + setEventMessage($mailfile->error, 'errors'); + } else { + $result = $mailfile->sendfile(); + if ($result) { + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; + $object->actionmsg2 = $actionmsg2; + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface = new Interfaces($db); + $result = $interface->run_triggers('PROPAL_SENTBYMAIL', $object, $user, $langs, $conf); + if ($result < 0) { + $error++; + $object->errors = $interface->errors; + } + // Fin appel triggers + + if (! $error) { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); + setEventMessage($mesg); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } else { + dol_print_error($db); + } + } else { + $langs->load("other"); + if ($mailfile->error) { + $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); + $mesg .= '
' . $mailfile->error; + } else { + $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + setEventMessage($mesg, 'errors'); + } + } + } else { + $langs->load("other"); + setEventMessage($langs->trans('ErrorMailRecipientIsEmpty') . '!', 'errors'); + dol_syslog($langs->trans('ErrorMailRecipientIsEmpty')); + } + } else { + $langs->load("other"); + setEventMessage($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")), 'errors'); + dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal"))); + } + } + + // Go back to draft + if ($action == 'modif' && $user->rights->propal->creer) { + $object->set_draft($user); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + else if ($action == "setabsolutediscount" && $user->rights->propal->creer) { + if ($_POST ["remise_id"]) { + if ($object->id > 0) { + $result = $object->insert_discount($_POST ["remise_id"]); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + } + } + + // Add line + else if ($action == 'addline' && $user->rights->propal->creer) { + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST ["options_" . $key]); + } + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); + $error ++; + } + + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + $pu_ht = 0; + $pu_ttc = 0; + $price_min = 0; + $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); + + $db->begin(); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // If prices fields are update + $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); + + // On defini prix unitaire + if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->client->price_level) + { + $pu_ht = $prod->multiprices[$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; + $price_min = $prod->multiprices_min[$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; + if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result >= 0) { + if (count($prodcustprice->lines) > 0) { + $found = true; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; + }else { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + }else { + setEventMessage($prodcustprice->error,'errors'); + } + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + } + + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + $date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); + $date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->client); + $localtax2_tx = get_localtax($tva_tx, 2, $object->client); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option); + + if ($result > 0) { $db->commit(); if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -332,411 +752,120 @@ else if ($action == 'add' && $user->rights->propal->creer) { propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); - exit(); + unset($_POST ['prod_entry_mode']); + + unset($_POST ['qty']); + unset($_POST ['type']); + unset($_POST ['remise_percent']); + unset($_POST ['price_ht']); + unset($_POST ['price_ttc']); + unset($_POST ['tva_tx']); + unset($_POST ['product_ref']); + unset($_POST ['product_label']); + unset($_POST ['product_desc']); + unset($_POST ['fournprice']); + unset($_POST ['buying_price']); + unset($_POST ['np_marginRate']); + unset($_POST ['np_markRate']); + unset($_POST ['dp_desc']); + unset($_POST ['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); } else { $db->rollback(); - } - } else { - dol_print_error($db, $object->error); - $db->rollback(); - exit(); - } - } - } -} -// Classify billed -else if ($action == 'classifybilled' && $user->rights->propal->cloturer) { - $object->cloture($user, 4, ''); -} - -// Reopen proposal -else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { - // prevent browser refresh from reopening proposal several times - if ($object->statut == 2 || $object->statut == 3) { - $object->reopen($user, 1); - } -} - -// Close proposal -else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) { - if (! GETPOST('statut')) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors'); - $action = 'statut'; - } else { - // prevent browser refresh from closing proposal several times - if ($object->statut == 1) { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); - } - } -} - -// Add file in email form -if (GETPOST('addfile')) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; - - dol_add_file_process($upload_dir_tmp, 0, 0); - $action = 'presend'; -} - -// Remove file in email form -if (GETPOST('removedfile')) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; - - // TODO Delete only files that was uploaded from email form - dol_remove_file_process($_POST ['removedfile'], 0); - $action = 'presend'; -} - -/* - * Send mail - */ -if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) { - $langs->load('mails'); - - if ($object->id > 0) { - if ($_POST ['sendto']) { - // Le destinataire a ete fourni via le champ libre - $sendto = $_POST ['sendto']; - $sendtoid = 0; - } elseif ($_POST ['receiver'] != '-1') { - // Recipient was provided from combo list - if ($_POST ['receiver'] == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } else // Id du contact - { - $sendto = $object->client->contact_get_property($_POST ['receiver'], 'email'); - $sendtoid = $_POST ['receiver']; - } - } - - if (dol_strlen($sendto)) { - $langs->load("commercial"); - - $from = $_POST ['fromname'] . ' <' . $_POST ['frommail'] . '>'; - $replyto = $_POST ['replytoname'] . ' <' . $_POST ['replytomail'] . '>'; - $message = $_POST ['message']; - $sendtocc = $_POST ['sendtocc']; - $deliveryreceipt = $_POST ['deliveryreceipt']; - - if (dol_strlen($_POST ['subject'])) - $subject = $_POST ['subject']; - else - $subject = $langs->transnoentities('Propal') . ' ' . $object->ref; - $actiontypecode = 'AC_PROP'; - $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; - if ($message) { - $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; - $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; - $actionmsg .= $message; - } - $actionmsg2 = $langs->transnoentities('Action' . $actiontypecode); - - // Create form object - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles = $formmail->get_attached_files(); - $filepath = $attachedfiles ['paths']; - $filename = $attachedfiles ['names']; - $mimetype = $attachedfiles ['mimes']; - - // Envoi de la propal - require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); - if ($mailfile->error) { - setEventMessage($mailfile->error, 'errors'); - } else { - $result = $mailfile->sendfile(); - if ($result) { - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface = new Interfaces($db); - $result = $interface->run_triggers('PROPAL_SENTBYMAIL', $object, $user, $langs, $conf); - if ($result < 0) { - $error++; - $object->errors = $interface->errors; - } - // Fin appel triggers - - if (! $error) { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); - setEventMessage($mesg); - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); - exit(); - } else { - dol_print_error($db); - } - } else { - $langs->load("other"); - if ($mailfile->error) { - $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); - $mesg .= '
' . $mailfile->error; - } else { - $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - setEventMessage($mesg, 'errors'); + setEventMessage($object->error, 'errors'); } } - } else { - $langs->load("other"); - setEventMessage($langs->trans('ErrorMailRecipientIsEmpty') . '!', 'errors'); - dol_syslog($langs->trans('ErrorMailRecipientIsEmpty')); - } - } else { - $langs->load("other"); - setEventMessage($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")), 'errors'); - dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal"))); - } -} - -// Go back to draft -if ($action == 'modif' && $user->rights->propal->creer) { - $object->set_draft($user); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } -} - -else if ($action == "setabsolutediscount" && $user->rights->propal->creer) { - if ($_POST ["remise_id"]) { - if ($object->id > 0) { - $result = $object->insert_discount($_POST ["remise_id"]); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } - } - } -} - -// Add line -else if ($action == 'addline' && $user->rights->propal->creer) { - - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') - { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; - } - - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST ["options_" . $key]); } } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; - } - - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); - $error ++; - } - - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - $pu_ht = 0; - $pu_ttc = 0; - $price_min = 0; - $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); - - $db->begin(); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); - - // If prices fields are update - $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); - - // On defini prix unitaire - if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->client->price_level) - { - $pu_ht = $prod->multiprices[$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; - $price_min = $prod->multiprices_min[$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; - if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result >= 0) { - if (count($prodcustprice->lines) > 0) { - $found = true; - $pu_ht = price($prodcustprice->lines[0]->price); - $pu_ttc = price($prodcustprice->lines[0]->price_ttc); - $price_base_type = $prodcustprice->lines[0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; - }else { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } - }else { - setEventMessage($prodcustprice->error,'errors'); - } - } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } - - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - } - - $desc = ''; - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; - } else { - $desc = $prod->description; - } - - $desc = dol_concatdesc($desc, $product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } - - $type = $prod->type; - } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); - } - - // Margin - $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); - - $date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->client); - $localtax2_tx = get_localtax($tva_tx, 2, $object->client); - + // Mise a jour d'une ligne dans la propale + else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) { + // Define info_bits $info_bits = 0; - if ($tva_npr) + if (preg_match('/\*/', GETPOST('tva_tx'))) $info_bits |= 0x01; - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option); + // Clean parameters + $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - if ($result > 0) { + // Define vat_rate + $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->client); + $localtax2_rate = get_localtax($vat_rate, 2, $object->client); + $pu_ht = GETPOST('price_ht'); + + // Add buying price + $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST ["options_" . $key]); + } + } + + // Define special_code for special lines + $special_code=GETPOST('special_code'); + if (! GETPOST('qty')) $special_code=3; + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) { + $product = new Product($db); + $res = $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min [$object->client->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + $error ++; + } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + } + + if (! $error) { + $db->begin(); + + $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option); + + if ($result >= 0) { $db->commit(); if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -751,10 +880,9 @@ else if ($action == 'addline' && $user->rights->propal->creer) { propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - unset($_POST ['prod_entry_mode']); - unset($_POST ['qty']); unset($_POST ['type']); + unset($_POST ['productid']); unset($_POST ['remise_percent']); unset($_POST ['price_ht']); unset($_POST ['price_ttc']); @@ -764,23 +892,6 @@ else if ($action == 'addline' && $user->rights->propal->creer) { unset($_POST ['product_desc']); unset($_POST ['fournprice']); unset($_POST ['buying_price']); - unset($_POST ['np_marginRate']); - unset($_POST ['np_markRate']); - unset($_POST ['dp_desc']); - unset($_POST ['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); } else { $db->rollback(); @@ -788,303 +899,194 @@ else if ($action == 'addline' && $user->rights->propal->creer) { } } } -} -// Mise a jour d'une ligne dans la propale -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) { - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', GETPOST('tva_tx'))) - $info_bits |= 0x01; - - // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - - // Define vat_rate - $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->client); - $localtax2_rate = get_localtax($vat_rate, 2, $object->client); - $pu_ht = GETPOST('price_ht'); - - // Add buying price - $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST ["options_" . $key]); - } + else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); } - // Define special_code for special lines - $special_code=GETPOST('special_code'); - if (! GETPOST('qty')) $special_code=3; - - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $res = $product->fetch($productid); - - $type = $product->type; - - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min [$object->client->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; + // Generation doc (depuis lien ou depuis cartouche doc) + else if ($action == 'builddoc' && $user->rights->propal->creer) { + if (GETPOST('model')) { + $object->setDocModel($user, GETPOST('model')); } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); } - } + $ret = $object->fetch($id); // Reload to get new records + $result = propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if (! $error) { - $db->begin(); - - $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option); - - if ($result >= 0) { - $db->commit(); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST ['qty']); - unset($_POST ['type']); - unset($_POST ['productid']); - unset($_POST ['remise_percent']); - unset($_POST ['price_ht']); - unset($_POST ['price_ttc']); - unset($_POST ['tva_tx']); - unset($_POST ['product_ref']); - unset($_POST ['product_label']); - unset($_POST ['product_desc']); - unset($_POST ['fournprice']); - unset($_POST ['buying_price']); + if ($result <= 0) { + dol_print_error($db, $result); + exit(); } else { - $db->rollback(); - - setEventMessage($object->error, 'errors'); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc')); + exit(); } } -} -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -// Generation doc (depuis lien ou depuis cartouche doc) -else if ($action == 'builddoc' && $user->rights->propal->creer) { - if (GETPOST('model')) { - $object->setDocModel($user, GETPOST('model')); - } - - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $result = propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - if ($result <= 0) { - dol_print_error($db, $result); - exit(); - } else { - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc')); - exit(); - } -} - -// Remove file in doc form -else if ($action == 'remove_file' && $user->rights->propal->creer) { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->propal->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); - else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); - } -} - -// Set project -else if ($action == 'classin' && $user->rights->propal->creer) { - $object->setProject($_POST ['projectid']); -} - -// Delai de livraison -else if ($action == 'setavailability' && $user->rights->propal->creer) { - $result = $object->availability($_POST ['availability_id']); -} - -// Origine de la propale -else if ($action == 'setdemandreason' && $user->rights->propal->creer) { - $result = $object->demand_reason($_POST ['demand_reason_id']); -} - -// Conditions de reglement -else if ($action == 'setconditions' && $user->rights->propal->creer) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); -} - -else if ($action == 'setremisepercent' && $user->rights->propal->creer) { - $result = $object->set_remise_percent($user, $_POST ['remise_percent']); -} - -else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) { - $result = $object->set_remise_absolue($user, $_POST ['remise_absolue']); -} - -// Mode de reglement -else if ($action == 'setmode' && $user->rights->propal->creer) { - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); -} - -/* - * Ordonnancement des lignes -*/ - -else if ($action == 'up' && $user->rights->propal->creer) { - $object->line_up(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'down' && $user->rights->propal->creer) { - $object->line_down(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); -} else if ($action == 'update_extras') { - // Fill array 'array_options' with data from update form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('propaldao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been - // modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) - $error ++; - } - - if ($error) - $action = 'edit_extras'; -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) { - if ($action == 'addcontact') { + // Remove file in doc form + else if ($action == 'remove_file' && $user->rights->propal->creer) { if ($object->id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST ["type"], $_POST ["source"]); + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->propal->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); + } + } + + // Set project + else if ($action == 'classin' && $user->rights->propal->creer) { + $object->setProject($_POST ['projectid']); + } + + // Delai de livraison + else if ($action == 'setavailability' && $user->rights->propal->creer) { + $result = $object->availability($_POST ['availability_id']); + } + + // Origine de la propale + else if ($action == 'setdemandreason' && $user->rights->propal->creer) { + $result = $object->demand_reason($_POST ['demand_reason_id']); + } + + // Conditions de reglement + else if ($action == 'setconditions' && $user->rights->propal->creer) { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + } + + else if ($action == 'setremisepercent' && $user->rights->propal->creer) { + $result = $object->set_remise_percent($user, $_POST ['remise_percent']); + } + + else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) { + $result = $object->set_remise_absolue($user, $_POST ['remise_absolue']); + } + + // Mode de reglement + else if ($action == 'setmode' && $user->rights->propal->creer) { + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + } + + /* + * Ordonnancement des lignes + */ + + else if ($action == 'up' && $user->rights->propal->creer) { + $object->line_up(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $langs->load("errors"); - setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'down' && $user->rights->propal->creer) { + $object->line_down(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) + $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('propaldao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been + // modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) { + if ($action == 'addcontact') { + if ($object->id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST ["type"], $_POST ["source"]); + } + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); } else { - setEventMessage($object->error, 'errors'); + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + } else { + setEventMessage($object->error, 'errors'); + } } } - } - // Bascule du statut d'un contact - else if ($action == 'swapstatut') { - if ($object->fetch($id) > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); - } else { - dol_print_error($db); + // Bascule du statut d'un contact + else if ($action == 'swapstatut') { + if ($object->fetch($id) > 0) { + $result = $object->swapContactStatus(GETPOST('ligne')); + } else { + dol_print_error($db); + } } - } - // Efface un contact - else if ($action == 'deletecontact') { - $object->fetch($id); - $result = $object->delete_contact($lineid); + // Efface un contact + else if ($action == 'deletecontact') { + $object->fetch($id); + $result = $object->delete_contact($lineid); - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - dol_print_error($db); + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + dol_print_error($db); + } } } } diff --git a/htdocs/comm/prospect/list.php b/htdocs/comm/prospect/list.php index 58a384df6d0..fdfa2495411 100644 --- a/htdocs/comm/prospect/list.php +++ b/htdocs/comm/prospect/list.php @@ -162,11 +162,13 @@ $hookmanager->initHooks(array('prospectlist')); $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters); // Note that $action and $object may have been modified by some hooks -if ($action == 'cstc') -{ - $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"]; - $sql .= " WHERE rowid = ".$_GET["socid"]; - $result=$db->query($sql); +if (empty($reshook)) { + if ($action == 'cstc') + { + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"]; + $sql .= " WHERE rowid = ".$_GET["socid"]; + $result=$db->query($sql); + } } diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 1c01b975a3b..02e6c74c13c 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -101,44 +101,88 @@ $permissionnote = $user->rights->commande->creer; // Used by the include of acti $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once +if (empty($reshook)) { -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer) -{ - if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer) { - $mesg='
'.$langs->trans("NoCloneOptionsSpecified").'
'; - } - else - { - if ($object->id > 0) + if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) { - // Because createFromClone modifies the object, we must clone it so that we can restore it later - $orig = dol_clone($object); + $mesg='
'.$langs->trans("NoCloneOptionsSpecified").'
'; + } + else + { + if ($object->id > 0) + { + // Because createFromClone modifies the object, we must clone it so that we can restore it later + $orig = dol_clone($object); - $result=$object->createFromClone($socid); + $result=$object->createFromClone($socid); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + $object = $orig; + $action=''; + } + } + } + } + + // Reopen a closed order + else if ($action == 'reopen' && $user->rights->commande->creer) { + if ($object->statut == 3) { + $result = $object->set_reopen($user); if ($result > 0) { - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } else { setEventMessage($object->error, 'errors'); - $object = $orig; - $action=''; } } } -} -// Reopen a closed order -else if ($action == 'reopen' && $user->rights->commande->creer) { - if ($object->statut == 3) { - $result = $object->set_reopen($user); - if ($result > 0) - { + // Suppression de la commande + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) { + $result = $object->delete($user); + if ($result > 0) { + header('Location: index.php'); + exit; + } + else { + setEventMessage($object->error, 'errors'); + } + } + + // Remove a product line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) { + $result = $object->deleteline($lineid); + if ($result > 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($object->id); // Reload to get new records + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } @@ -147,697 +191,299 @@ else if ($action == 'reopen' && $user->rights->commande->creer) { setEventMessage($object->error, 'errors'); } } -} -// Suppression de la commande -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) { - $result = $object->delete($user); - if ($result > 0) { - header('Location: index.php'); - exit; + // Categorisation dans projet + else if ($action == 'classin' && $user->rights->commande->creer) { + $object->setProject(GETPOST('projectid')); } - else { - setEventMessage($object->error, 'errors'); - } -} -// Remove a product line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) { - $result = $object->deleteline($lineid); - if ($result > 0) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($object->id); // Reload to get new records - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Add order + else if ($action == 'add' && $user->rights->commande->creer) { + $datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + + if ($datecommande == '') { + $mesg = '
' . $langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')) . '
'; + $action = 'create'; + $error ++; } - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - setEventMessage($object->error, 'errors'); - } -} + if ($socid < 1) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + $action = 'create'; + $error ++; + } -// Categorisation dans projet -else if ($action == 'classin' && $user->rights->commande->creer) { - $object->setProject(GETPOST('projectid')); -} + if (! $error) { + $object->socid = $socid; + $object->fetch_thirdparty(); -// Add order -else if ($action == 'add' && $user->rights->commande->creer) { - $datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + $db->begin(); - if ($datecommande == '') { - $mesg = '
' . $langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')) . '
'; - $action = 'create'; - $error ++; - } + $object->date_commande = $datecommande; + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + $object->source = GETPOST('source_id'); + $object->fk_project = GETPOST('projectid'); + $object->ref_client = GETPOST('ref_client'); + $object->modelpdf = GETPOST('model'); + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->date_livraison = $datelivraison; + $object->fk_delivery_address = GETPOST('fk_address'); + $object->contactid = GETPOST('contactidp'); - if ($socid < 1) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - $action = 'create'; - $error ++; - } + // If creation from another object of another module (Example: origin=propal, originid=1) + if (! empty($origin) && ! empty($originid)) { + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { + $element = $regs [1]; + $subelement = $regs [2]; + } - if (! $error) { - $object->socid = $socid; - $object->fetch_thirdparty(); + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } - $db->begin(); + $object->origin = $origin; + $object->origin_id = $originid; - $object->date_commande = $datecommande; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); - $object->source = GETPOST('source_id'); - $object->fk_project = GETPOST('projectid'); - $object->ref_client = GETPOST('ref_client'); - $object->modelpdf = GETPOST('model'); - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->date_livraison = $datelivraison; - $object->fk_delivery_address = GETPOST('fk_address'); - $object->contactid = GETPOST('contactidp'); + // Possibility to add external linked objects with hooks + $object->linked_objects [$object->origin] = $object->origin_id; + $other_linked_objects = GETPOST('other_linked_objects', 'array'); + if (! empty($other_linked_objects)) { + $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); + } - // If creation from another object of another module (Example: origin=propal, originid=1) - if (! empty($origin) && ! empty($originid)) { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { - $element = $regs [1]; - $subelement = $regs [2]; - } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) + $error ++; - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; - $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - - $object->origin = $origin; - $object->origin_id = $originid; - - // Possibility to add external linked objects with hooks - $object->linked_objects [$object->origin] = $object->origin_id; - $other_linked_objects = GETPOST('other_linked_objects', 'array'); - if (! empty($other_linked_objects)) { - $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) - $error ++; - - if (! $error) - { - $object_id = $object->create($user); - - if ($object_id > 0) + if (! $error) { - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + $object_id = $object->create($user); - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) + if ($object_id > 0) { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) { - $srcobject->fetch_lines(); $lines = $srcobject->lines; - } - - $fk_parent_line = 0; - $num = count($lines); - - for($i = 0; $i < $num; $i ++) - { - $label = (! empty($lines [$i]->label) ? $lines [$i]->label : ''); - $desc = (! empty($lines [$i]->desc) ? $lines [$i]->desc : $lines [$i]->libelle); - $product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0); - - // Dates - // TODO mutualiser - $date_start = $lines [$i]->date_debut_prevue; - if ($lines [$i]->date_debut_reel) - $date_start = $lines [$i]->date_debut_reel; - if ($lines [$i]->date_start) - $date_start = $lines [$i]->date_start; - $date_end = $lines [$i]->date_fin_prevue; - if ($lines [$i]->date_fin_reel) - $date_end = $lines [$i]->date_fin_reel; - if ($lines [$i]->date_end) - $date_end = $lines [$i]->date_end; - - // Reset fk_parent_line for no child products and special product - if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) // For avoid conflicts if - // trigger used + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) { - $lines [$i]->fetch_optionals($lines [$i]->rowid); - $array_option = $lines [$i]->array_options; + $srcobject->fetch_lines(); + $lines = $srcobject->lines; } - $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); + $fk_parent_line = 0; + $num = count($lines); - if ($result < 0) { + for($i = 0; $i < $num; $i ++) + { + $label = (! empty($lines [$i]->label) ? $lines [$i]->label : ''); + $desc = (! empty($lines [$i]->desc) ? $lines [$i]->desc : $lines [$i]->libelle); + $product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0); + + // Dates + // TODO mutualiser + $date_start = $lines [$i]->date_debut_prevue; + if ($lines [$i]->date_debut_reel) + $date_start = $lines [$i]->date_debut_reel; + if ($lines [$i]->date_start) + $date_start = $lines [$i]->date_start; + $date_end = $lines [$i]->date_fin_prevue; + if ($lines [$i]->date_fin_reel) + $date_end = $lines [$i]->date_fin_reel; + if ($lines [$i]->date_end) + $date_end = $lines [$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) // For avoid conflicts if + // trigger used + { + $lines [$i]->fetch_optionals($lines [$i]->rowid); + $array_option = $lines [$i]->array_options; + } + + $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); + + if ($result < 0) { + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines [$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) $error ++; - break; - } - - // Defined the new fk_parent_line - if ($result > 0 && $lines [$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - - // Hooks - $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) + } else { + $mesg = $srcobject->error; $error ++; + } } else { - $mesg = $srcobject->error; + $mesg = $object->error; $error ++; } } else { - $mesg = $object->error; - $error ++; + // Required extrafield left blank, error message already defined by setOptionalsFromPost() + $action = 'create'; } } else { - // Required extrafield left blank, error message already defined by setOptionalsFromPost() - $action = 'create'; - } - } else { - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) - $error ++; - - if (! $error) { - $object_id = $object->create($user); - - // If some invoice's lines already known - $NBLINES = 8; - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST ['idprod' . $i]) { - $xid = 'idprod' . $i; - $xqty = 'qty' . $i; - $xremise = 'remise_percent' . $i; - $object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]); - } - } - } - } - - // Insert default contacts if defined - if ($object_id > 0) { - if (GETPOST('contactidp')) { - $result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external'); - if ($result < 0) { - $mesg = '
' . $langs->trans("ErrorFailedToAddContact") . '
'; + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error ++; - } - } - $id = $object_id; - $action = ''; - } + if (! $error) { + $object_id = $object->create($user); - // End of object creation, we show it - if ($object_id > 0 && ! $error) { - $db->commit(); - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id); - exit(); - } else { - $db->rollback(); - $action = 'create'; - if (! $mesg) - $mesg = '
' . $object->error . '
'; - } - } -} - -else if ($action == 'classifybilled' && $user->rights->commande->creer) -{ - $ret=$object->classifyBilled(); - - if ($ret < 0) { - setEventMessage($object->error, 'errors'); - } -} - -// Positionne ref commande client -else if ($action == 'set_ref_client' && $user->rights->commande->creer) { - $object->set_ref_client($user, GETPOST('ref_client')); -} - -else if ($action == 'setremise' && $user->rights->commande->creer) { - $object->set_remise($user, GETPOST('remise')); -} - -else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) { - if (GETPOST('remise_id')) { - if ($object->id > 0) { - $object->insert_discount(GETPOST('remise_id')); - } else { - dol_print_error($db, $object->error); - } - } -} - -else if ($action == 'setdate' && $user->rights->commande->creer) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year')); - - $result = $object->set_date($user, $date); - if ($result < 0) { - $mesg = '
' . $object->error . '
'; - } -} - -else if ($action == 'setdate_livraison' && $user->rights->commande->creer) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); - - $result = $object->set_date_livraison($user, $datelivraison); - if ($result < 0) { - $mesg = '
' . $object->error . '
'; - } -} - -else if ($action == 'setmode' && $user->rights->commande->creer) { - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setavailability' && $user->rights->commande->creer) { - $result = $object->availability(GETPOST('availability_id')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setdemandreason' && $user->rights->commande->creer) { - $result = $object->demand_reason(GETPOST('demand_reason_id')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setconditions' && $user->rights->commande->creer) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); - if ($result < 0) { - dol_print_error($db, $object->error); - } else { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = GETPOST('lang_id', 'alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($object->id); // Reload to get new records - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } -} - -else if ($action == 'setremisepercent' && $user->rights->commande->creer) { - $result = $object->set_remise($user, GETPOST('remise_percent')); -} - -else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) { - $result = $object->set_remise_absolue($user, GETPOST('remise_absolue')); -} - -// Add a new line -else if ($action == 'addline' && $user->rights->commande->creer) { - $langs->load('errors'); - $error = 0; - - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') - { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; - } - - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST ["options_" . $key]); - } - } - - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if ($qty == '') { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error ++; - } - - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - // Clean parameters - $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); - $date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); - - // Update if prices fields are defined - $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); - - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - { - $pu_ht = $prod->multiprices [$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc [$object->client->price_level]; - $price_min = $prod->multiprices_min [$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type [$object->client->price_level]; - if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result >= 0) { - if (count($prodcustprice->lines) > 0) { - $found = true; - $pu_ht = price($prodcustprice->lines[0]->price); - $pu_ttc = price($prodcustprice->lines[0]->price_ttc); - $price_base_type = $prodcustprice->lines[0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; - } else { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; + // If some invoice's lines already known + $NBLINES = 8; + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST ['idprod' . $i]) { + $xid = 'idprod' . $i; + $xqty = 'qty' . $i; + $xremise = 'remise_percent' . $i; + $object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]); } - } else { - setEventMessage($prodcustprice->error,'errors'); } } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } + } - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + // Insert default contacts if defined + if ($object_id > 0) { + if (GETPOST('contactidp')) { + $result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external'); + if ($result < 0) { + $mesg = '
' . $langs->trans("ErrorFailedToAddContact") . '
'; + $error ++; } } - $desc = ''; + $id = $object_id; + $action = ''; + } - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; - } else { - $desc = $prod->description; - } - - $desc = dol_concatdesc($desc, $product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } - - $type = $prod->type; - } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); - } - - // Margin - $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->client); - $localtax2_tx = get_localtax($tva_tx, 2, $object->client); - - $desc = dol_htmlcleanlastbr($desc); - - $info_bits = 0; - if ($tva_npr) - $info_bits |= 0x01; - - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); - - if ($result > 0) { - $ret = $object->fetch($object->id); // Reload to get new records - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = GETPOST('lang_id', 'alpha'); - if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST ['prod_entry_mode']); - - unset($_POST ['qty']); - unset($_POST ['type']); - unset($_POST ['remise_percent']); - unset($_POST ['price_ht']); - unset($_POST ['price_ttc']); - unset($_POST ['tva_tx']); - unset($_POST ['product_ref']); - unset($_POST ['product_label']); - unset($_POST ['product_desc']); - unset($_POST ['fournprice']); - unset($_POST ['buying_price']); - unset($_POST ['np_marginRate']); - unset($_POST ['np_markRate']); - unset($_POST ['dp_desc']); - unset($_POST ['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); + // End of object creation, we show it + if ($object_id > 0 && ! $error) { + $db->commit(); + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id); + exit(); } else { - setEventMessage($object->error, 'errors'); + $db->rollback(); + $action = 'create'; + if (! $mesg) + $mesg = '
' . $object->error . '
'; } } } -} -/* - * Mise a jour d'une ligne dans la commande -*/ -else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) { - // Clean parameters - $date_start=''; - $date_end=''; - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht=GETPOST('price_ht'); - $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + else if ($action == 'classifybilled' && $user->rights->commande->creer) + { + $ret=$object->classifyBilled(); - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', $vat_rate)) - $info_bits |= 0x01; - - // Define vat_rate - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->client); - $localtax2_rate = get_localtax($vat_rate, 2, $object->client); - - // Add buying price - $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - // Extrafields Lines - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield POST Data - if (is_array($extralabelsline)) { - foreach ($extralabelsline as $key => $value) { - unset($_POST ["options_" . $key]); + if ($ret < 0) { + setEventMessage($object->error, 'errors'); } } - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $product->fetch($productid); + // Positionne ref commande client + else if ($action == 'set_ref_client' && $user->rights->commande->creer) { + $object->set_ref_client($user, GETPOST('ref_client')); + } - $type = $product->type; + else if ($action == 'setremise' && $user->rights->commande->creer) { + $object->set_remise($user, GETPOST('remise')); + } - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min [$object->client->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; - } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; + else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) { + if (GETPOST('remise_id')) { + if ($object->id > 0) { + $object->insert_discount(GETPOST('remise_id')); + } else { + dol_print_error($db, $object->error); + } } } - if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); + else if ($action == 'setdate' && $user->rights->commande->creer) { + // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year')); - if ($result >= 0) { + $result = $object->set_date($user, $date); + if ($result < 0) { + $mesg = '
' . $object->error . '
'; + } + } + + else if ($action == 'setdate_livraison' && $user->rights->commande->creer) { + // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + + $result = $object->set_date_livraison($user, $datelivraison); + if ($result < 0) { + $mesg = '
' . $object->error . '
'; + } + } + + else if ($action == 'setmode' && $user->rights->commande->creer) { + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setavailability' && $user->rights->commande->creer) { + $result = $object->availability(GETPOST('availability_id')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setdemandreason' && $user->rights->commande->creer) { + $result = $object->demand_reason(GETPOST('demand_reason_id')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setconditions' && $user->rights->commande->creer) { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + if ($result < 0) { + dol_print_error($db, $object->error); + } else { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); + $newlang = GETPOST('lang_id', 'alpha'); if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->client->default_lang; if (! empty($newlang)) { @@ -848,491 +494,848 @@ else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST(' $ret = $object->fetch($object->id); // Reload to get new records commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } + } + } - unset($_POST ['qty']); - unset($_POST ['type']); - unset($_POST ['productid']); - unset($_POST ['remise_percent']); - unset($_POST ['price_ht']); - unset($_POST ['price_ttc']); - unset($_POST ['tva_tx']); - unset($_POST ['product_ref']); - unset($_POST ['product_label']); - unset($_POST ['product_desc']); - unset($_POST ['fournprice']); - unset($_POST ['buying_price']); + else if ($action == 'setremisepercent' && $user->rights->commande->creer) { + $result = $object->set_remise($user, GETPOST('remise_percent')); + } + + else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) { + $result = $object->set_remise_absolue($user, GETPOST('remise_absolue')); + } + + // Add a new line + else if ($action == 'addline' && $user->rights->commande->creer) { + $langs->load('errors'); + $error = 0; + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST ["options_" . $key]); + } + } + + if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if ($qty == '') { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error ++; + } + + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + // Clean parameters + $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); + $date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // Update if prices fields are defined + $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); + + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + { + $pu_ht = $prod->multiprices [$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc [$object->client->price_level]; + $price_min = $prod->multiprices_min [$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type [$object->client->price_level]; + if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result >= 0) { + if (count($prodcustprice->lines) > 0) { + $found = true; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; + } else { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + } else { + setEventMessage($prodcustprice->error,'errors'); + } + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + } + + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->client); + $localtax2_tx = get_localtax($tva_tx, 2, $object->client); + + $desc = dol_htmlcleanlastbr($desc); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); + + if ($result > 0) { + $ret = $object->fetch($object->id); // Reload to get new records + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = GETPOST('lang_id', 'alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST ['prod_entry_mode']); + + unset($_POST ['qty']); + unset($_POST ['type']); + unset($_POST ['remise_percent']); + unset($_POST ['price_ht']); + unset($_POST ['price_ttc']); + unset($_POST ['tva_tx']); + unset($_POST ['product_ref']); + unset($_POST ['product_label']); + unset($_POST ['product_desc']); + unset($_POST ['fournprice']); + unset($_POST ['buying_price']); + unset($_POST ['np_marginRate']); + unset($_POST ['np_markRate']); + unset($_POST ['dp_desc']); + unset($_POST ['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + } else { + setEventMessage($object->error, 'errors'); + } + } + } + } + + /* + * Mise a jour d'une ligne dans la commande + */ + else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) { + // Clean parameters + $date_start=''; + $date_end=''; + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht=GETPOST('price_ht'); + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; + + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->client); + $localtax2_rate = get_localtax($vat_rate, 2, $object->client); + + // Add buying price + $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST ["options_" . $key]); + } + } + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) { + $product = new Product($db); + $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min [$object->client->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + $error ++; + } } else { - setEventMessage($object->error, 'errors'); - } - } -} + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); -else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) { - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; - $action=''; - } - } - - if (! $error) { - $result = $object->valid($user, $idwarehouse); - if ($result >= 0) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - } -} -// Go back to draft status -else if ($action == 'confirm_modif' && $user->rights->commande->creer) { - $idwarehouse = GETPOST('idwarehouse'); + if (! $error) { + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } + if ($result >= 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; - $action=''; - } - } + $ret = $object->fetch($object->id); // Reload to get new records + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } - if (! $error) { - $result = $object->set_draft($user, $idwarehouse); - if ($result >= 0) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($object->id); // Reload to get new records - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + unset($_POST ['qty']); + unset($_POST ['type']); + unset($_POST ['productid']); + unset($_POST ['remise_percent']); + unset($_POST ['price_ht']); + unset($_POST ['price_ttc']); + unset($_POST ['tva_tx']); + unset($_POST ['product_ref']); + unset($_POST ['product_label']); + unset($_POST ['product_desc']); + unset($_POST ['fournprice']); + unset($_POST ['buying_price']); + } else { + setEventMessage($object->error, 'errors'); } } } -} -else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) { - $result = $object->cloture($user); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } -} - -else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) { - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); + else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); } - // Check parameters - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) - { - if (! $idwarehouse || $idwarehouse == -1) + else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) { + $idwarehouse = GETPOST('idwarehouse'); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $error++; - $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; - $action=''; + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; + $action=''; + } + } + + if (! $error) { + $result = $object->valid($user, $idwarehouse); + if ($result >= 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } } } - if (! $error) { - $result = $object->cancel($idwarehouse); + // Go back to draft status + else if ($action == 'confirm_modif' && $user->rights->commande->creer) { + $idwarehouse = GETPOST('idwarehouse'); + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; + $action=''; + } + } + + if (! $error) { + $result = $object->set_draft($user, $idwarehouse); + if ($result >= 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($object->id); // Reload to get new records + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } + } + + else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) { + $result = $object->cloture($user); if ($result < 0) { setEventMessage($object->error, 'errors'); } } -} -/* - * Ordonnancement des lignes -*/ + else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) { + $idwarehouse = GETPOST('idwarehouse'); -else if ($action == 'up' && $user->rights->commande->creer) { - $object->line_up(GETPOST('rowid')); + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // Check parameters + if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + $mesgs[]='
'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'
'; + $action=''; + } + } + + if (! $error) { + $result = $object->cancel($idwarehouse); + + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'down' && $user->rights->commande->creer) { - $object->line_down(GETPOST('rowid')); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); - exit(); -} - -else if ($action == 'builddoc') // In get or post -{ /* - * Generate order document - * define into /core/modules/commande/modules_commande.php - */ + * Ordonnancement des lignes + */ - // Save last template used to generate document - if (GETPOST('model')) - $object->setDocModel($user, GETPOST('model', 'alpha')); + else if ($action == 'up' && $user->rights->commande->creer) { + $object->line_up(GETPOST('rowid')); // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $result = commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } - if ($result <= 0) { - dol_print_error($db, $result); + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); exit(); } -} -// Remove file in doc form -else if ($action == 'remove_file') { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + else if ($action == 'down' && $user->rights->commande->creer) { + $object->line_down(GETPOST('rowid')); - $langs->load("other"); - $upload_dir = $conf->commande->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'builddoc') // In get or post + { + /* + * Generate order document + * define into /core/modules/commande/modules_commande.php + */ + + // Save last template used to generate document + if (GETPOST('model')) + $object->setDocModel($user, GETPOST('model', 'alpha')); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $result = commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($result <= 0) { + dol_print_error($db, $result); + exit(); + } + } + + // Remove file in doc form + else if ($action == 'remove_file') { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->commande->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action = ''; + } + } + + // Print file + else if ($action == 'print_file' and $user->rights->printipp->read) { + require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; + $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); + $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); + setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file'))); $action = ''; } -} -// Print file -else if ($action == 'print_file' and $user->rights->printipp->read) { - require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file'))); - $action = ''; -} - -else if ($action == 'update_extras') { - // Fill array 'array_options' with data from update form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('orderdao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) + else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('orderdao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; } - if ($error) - $action = 'edit_extras'; -} + /* + * Add file in email form + */ + if (GETPOST('addfile')) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; -/* - * Add file in email form -*/ -if (GETPOST('addfile')) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // Set tmp user directory TODO Use a dedicated directory for temp mails files + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; + dol_add_file_process($upload_dir_tmp, 0, 0); + $action = 'presend'; + } - dol_add_file_process($upload_dir_tmp, 0, 0); - $action = 'presend'; -} + /* + * Remove file in email form + */ + if (GETPOST('removedfile')) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; -/* - * Remove file in email form -*/ -if (GETPOST('removedfile')) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // Set tmp user directory + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; - // Set tmp user directory - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; + // TODO Delete only files that was uploaded from email form + dol_remove_file_process(GETPOST('removedfile'), 0); + $action = 'presend'; + } - // TODO Delete only files that was uploaded from email form - dol_remove_file_process(GETPOST('removedfile'), 0); - $action = 'presend'; -} + /* + * Send mail + */ + if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) { + $langs->load('mails'); -/* - * Send mail -*/ -if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) { - $langs->load('mails'); + if ($object->id > 0) { + // $ref = dol_sanitizeFileName($object->ref); + // $file = $conf->commande->dir_output . '/' . $ref . '/' . $ref . '.pdf'; - if ($object->id > 0) { - // $ref = dol_sanitizeFileName($object->ref); - // $file = $conf->commande->dir_output . '/' . $ref . '/' . $ref . '.pdf'; - - // if (is_readable($file)) - // { - if (GETPOST('sendto')) { - // Le destinataire a ete fourni via le champ libre - $sendto = GETPOST('sendto'); - $sendtoid = 0; - } elseif (GETPOST('receiver') != '-1') { - // Recipient was provided from combo list - if (GETPOST('receiver') == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; + // if (is_readable($file)) + // { + if (GETPOST('sendto')) { + // Le destinataire a ete fourni via le champ libre + $sendto = GETPOST('sendto'); $sendtoid = 0; - } else // Id du contact - { - $sendto = $object->client->contact_get_property(GETPOST('receiver'), 'email'); - $sendtoid = GETPOST('receiver'); - } - } - - if (dol_strlen($sendto)) { - $langs->load("commercial"); - - $from = GETPOST('fromname') . ' <' . GETPOST('frommail') . '>'; - $replyto = GETPOST('replytoname') . ' <' . GETPOST('replytomail') . '>'; - $message = GETPOST('message'); - $sendtocc = GETPOST('sendtocc'); - $deliveryreceipt = GETPOST('deliveryreceipt'); - - if ($action == 'send') { - if (dol_strlen(GETPOST('subject'))) - $subject = GETPOST('subject'); - else - $subject = $langs->transnoentities('Order') . ' ' . $object->ref; - $actiontypecode = 'AC_COM'; - $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; - if ($message) { - $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; - $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; - $actionmsg .= $message; + } elseif (GETPOST('receiver') != '-1') { + // Recipient was provided from combo list + if (GETPOST('receiver') == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } else // Id du contact + { + $sendto = $object->client->contact_get_property(GETPOST('receiver'), 'email'); + $sendtoid = GETPOST('receiver'); } - $actionmsg2 = $langs->transnoentities('Action' . $actiontypecode); } - // Create form object - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); + if (dol_strlen($sendto)) { + $langs->load("commercial"); - $attachedfiles = $formmail->get_attached_files(); - $filepath = $attachedfiles ['paths']; - $filename = $attachedfiles ['names']; - $mimetype = $attachedfiles ['mimes']; + $from = GETPOST('fromname') . ' <' . GETPOST('frommail') . '>'; + $replyto = GETPOST('replytoname') . ' <' . GETPOST('replytomail') . '>'; + $message = GETPOST('message'); + $sendtocc = GETPOST('sendtocc'); + $deliveryreceipt = GETPOST('deliveryreceipt'); - // Send mail - require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); - if ($mailfile->error) { - $mesg = '
' . $mailfile->error . '
'; - } else { - $result = $mailfile->sendfile(); - if ($result) { - $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); // Must not - // contains " - - $error = 0; - - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface = new Interfaces($db); - $result = $interface->run_triggers('ORDER_SENTBYMAIL', $object, $user, $langs, $conf); - if ($result < 0) { - $error ++; - $this->errors = $interface->errors; + if ($action == 'send') { + if (dol_strlen(GETPOST('subject'))) + $subject = GETPOST('subject'); + else + $subject = $langs->transnoentities('Order') . ' ' . $object->ref; + $actiontypecode = 'AC_COM'; + $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; + if ($message) { + $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; + $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; + $actionmsg .= $message; } - // Fin appel triggers + $actionmsg2 = $langs->transnoentities('Action' . $actiontypecode); + } - if ($error) { - dol_print_error($db); - } else { - // Redirect here - // This avoid sending mail twice if going out and then back to page - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&mesg=' . urlencode($mesg)); - exit(); - } + // Create form object + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles = $formmail->get_attached_files(); + $filepath = $attachedfiles ['paths']; + $filename = $attachedfiles ['names']; + $mimetype = $attachedfiles ['mimes']; + + // Send mail + require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); + if ($mailfile->error) { + $mesg = '
' . $mailfile->error . '
'; } else { - $langs->load("other"); - $mesg = '
'; - if ($mailfile->error) { - $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); - $mesg .= '
' . $mailfile->error; + $result = $mailfile->sendfile(); + if ($result) { + $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); // Must not + // contains " + + $error = 0; + + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; + $object->actionmsg2 = $actionmsg2; + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface = new Interfaces($db); + $result = $interface->run_triggers('ORDER_SENTBYMAIL', $object, $user, $langs, $conf); + if ($result < 0) { + $error ++; + $this->errors = $interface->errors; + } + // Fin appel triggers + + if ($error) { + dol_print_error($db); + } else { + // Redirect here + // This avoid sending mail twice if going out and then back to page + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&mesg=' . urlencode($mesg)); + exit(); + } } else { - $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + $langs->load("other"); + $mesg = '
'; + if ($mailfile->error) { + $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); + $mesg .= '
' . $mailfile->error; + } else { + $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg .= '
'; } - $mesg .= '
'; + } + /* } + else + { + $langs->load("other"); + $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; + $action='presend'; + dol_syslog('Recipient email is empty'); + }*/ + } else { + $langs->load("errors"); + $mesg = '
' . $langs->trans('ErrorCantReadFile', $file) . '
'; + dol_syslog('Failed to read file: ' . $file); + } + } else { + $langs->load("other"); + $mesg = '
' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")) . '
'; + dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Order"))); + } + } + + if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) { + if ($action == 'addcontact') { + if ($object->id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); + } + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + $mesg = '
' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '
'; + } else { + $mesg = '
' . $object->error . '
'; } } - /* } - else - { - $langs->load("other"); - $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; - $action='presend'; - dol_syslog('Recipient email is empty'); - }*/ - } else { - $langs->load("errors"); - $mesg = '
' . $langs->trans('ErrorCantReadFile', $file) . '
'; - dol_syslog('Failed to read file: ' . $file); - } - } else { - $langs->load("other"); - $mesg = '
' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")) . '
'; - dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Order"))); - } -} - -if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) { - if ($action == 'addcontact') { - if ($object->id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); } - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $langs->load("errors"); - $mesg = '
' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '
'; + // bascule du statut d'un contact + else if ($action == 'swapstatut') { + if ($object->id > 0) { + $result = $object->swapContactStatus(GETPOST('ligne')); } else { - $mesg = '
' . $object->error . '
'; + dol_print_error($db); } } - } - // bascule du statut d'un contact - else if ($action == 'swapstatut') { - if ($object->id > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); - } else { - dol_print_error($db); - } - } + // Efface un contact + else if ($action == 'deletecontact') { + $result = $object->delete_contact($lineid); - // Efface un contact - else if ($action == 'deletecontact') { - $result = $object->delete_contact($lineid); - - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - dol_print_error($db); + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + dol_print_error($db); + } } } } diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index c6214f449cb..a3403e0d9dd 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -111,71 +111,1342 @@ $permissionnote = $user->rights->facture->creer; // Used by the include of actio $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once +if (empty($reshook)) { -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { - if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { - $mesgs [] = '
' . $langs->trans("NoCloneOptionsSpecified") . '
'; - } else { - if ($object->fetch($id) > 0) { - $result = $object->createFromClone($socid); + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + // Action clone object + if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { + if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) { + $mesgs [] = '
' . $langs->trans("NoCloneOptionsSpecified") . '
'; + } else { + if ($object->fetch($id) > 0) { + $result = $object->createFromClone($socid); + if ($result > 0) { + header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result); + exit(); + } else { + setEventMessage($object->error, 'errors'); + $action = ''; + } + } + } + } + + // Change status of invoice + else if ($action == 'reopen' && $user->rights->facture->creer) { + $result = $object->fetch($id); + if ($object->statut == 2 || ($object->statut == 3 && $object->close_code != 'replaced')) { + $result = $object->set_unpaid($user); if ($result > 0) { - header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); exit(); } else { setEventMessage($object->error, 'errors'); + } + } + } + + // Delete invoice + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) { + $result = $object->fetch($id); + $object->fetch_thirdparty(); + + $idwarehouse = GETPOST('idwarehouse'); + + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); + } else { + $qualified_for_stock_change = $object->hasProductsOrServices(1); + } + + $result = $object->delete(0, 0, $idwarehouse); + if ($result > 0) { + header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); + exit(); + } else { + setEventMessage($object->error, 'errors'); + $action=''; + } + } + + // Delete line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) { + $object->fetch($id); + $object->fetch_thirdparty(); + + $result = $object->deleteline($_GET ['lineid'], $user); + if ($result > 0) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($id); // Reload to get new records + $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + if ($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + exit(); + } + } else { + setEventMessage($object->error, 'errors'); + $action = ''; + } + } + + // Delete link of credit note to invoice + else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) { + $discount = new DiscountAbsolute($db); + $result = $discount->fetch($_GET ["discountid"]); + $discount->unlink_invoice(); + } + + // Validation + else if ($action == 'valid' && $user->rights->facture->creer) { + $object->fetch($id); + + // On verifie signe facture + if ($object->type == Facture::TYPE_CREDIT_NOTE) { + // Si avoir, le signe doit etre negatif + if ($object->total_ht >= 0) { + $mesgs [] = '
' . $langs->trans("ErrorInvoiceAvoirMustBeNegative") . '
'; + $action = ''; + } + } else { + // Si non avoir, le signe doit etre positif + if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) { + $mesgs [] = '
' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive") . '
'; $action = ''; } } } -} -// Change status of invoice -else if ($action == 'reopen' && $user->rights->facture->creer) { - $result = $object->fetch($id); - if ($object->statut == 2 || ($object->statut == 3 && $object->close_code != 'replaced')) { - $result = $object->set_unpaid($user); - if ($result > 0) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); - exit(); - } else { - setEventMessage($object->error, 'errors'); + else if ($action == 'set_thirdparty' && $user->rights->facture->creer) { + $object->fetch($id); + $object->setValueFrom('fk_soc', $socid); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + exit(); + } + + else if ($action == 'classin' && $user->rights->facture->creer) { + $object->fetch($id); + $object->setProject($_POST['projectid']); + } + + else if ($action == 'setmode' && $user->rights->facture->creer) { + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setinvoicedate' && $user->rights->facture->creer) + { + $object->fetch($id); + $old_date_lim_reglement = $object->date_lim_reglement; + $date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']); + if (empty($date)) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate'); + exit; + } + $object->date=$date; + $new_date_lim_reglement = $object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; + $result = $object->update($user); + if ($result < 0) dol_print_error($db, $object->error); + } + + else if ($action == 'setconditions' && $user->rights->facture->creer) { + $object->fetch($id); + $object->cond_reglement_code = 0; // To clean property + $object->cond_reglement_id = 0; // To clean property + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + if ($result < 0) dol_print_error($db, $object->error); + + $old_date_lim_reglement = $object->date_lim_reglement; + $new_date_lim_reglement = $object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; + $result = $object->update($user); + if ($result < 0) dol_print_error($db, $object->error); + } + + else if ($action == 'setpaymentterm' && $user->rights->facture->creer) { + $object->fetch($id); + $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']); + if ($object->date_lim_reglement < $object->date) { + $object->date_lim_reglement = $object->calculate_date_lim_reglement(); + setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), 'warnings'); + } + $result = $object->update($user); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) { + $object->fetch($id); + $object->revenuestamp = GETPOST('revenuestamp'); + $result = $object->update($user); + $object->update_price(1); + if ($result < 0) + dol_print_error($db, $object->error); + } + + else if ($action == 'setremisepercent' && $user->rights->facture->creer) { + $object->fetch($id); + $result = $object->set_remise($user, $_POST['remise_percent']); + } + + else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { + // POST[remise_id] ou POST[remise_id_for_payment] + if (! empty($_POST["remise_id"])) { + $ret = $object->fetch($id); + if ($ret > 0) { + $result = $object->insert_discount($_POST["remise_id"]); + if ($result < 0) { + $mesgs [] = '
' . $object->error . '
'; + } + } else { + dol_print_error($db, $object->error); + } + } + if (! empty($_POST["remise_id_for_payment"])) { + require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; + $discount = new DiscountAbsolute($db); + $discount->fetch($_POST["remise_id_for_payment"]); + + $result = $discount->link_to_invoice(0, $id); + if ($result < 0) { + $mesgs [] = '
' . $discount->error . '
'; + } } } -} -// Delete invoice -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) { - $result = $object->fetch($id); - $object->fetch_thirdparty(); - - $idwarehouse = GETPOST('idwarehouse'); - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); + else if ($action == 'set_ref_client' && $user->rights->facture->creer) { + $object->fetch($id); + $object->set_ref_client($_POST['ref_client']); } - $result = $object->delete(0, 0, $idwarehouse); - if ($result > 0) { - header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php'); + // Classify to validated + else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) + { + $idwarehouse = GETPOST('idwarehouse'); + + $object->fetch($id); + $object->fetch_thirdparty(); + + // Check parameters + + // Check for mandatory prof id + for($i = 1; $i < 6; $i ++) + { + $idprof_mandatory = 'SOCIETE_IDPROF' . ($i) . '_INVOICE_MANDATORY'; + $idprof = 'idprof' . $i; + if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) { + if (! $error) + $langs->load("errors"); + $error ++; + + setEventMessage($langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId' . $i, $object->thirdparty->country_code)), 'errors'); + } + } + + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); + } else { + $qualified_for_stock_change = $object->hasProductsOrServices(1); + } + + // Check for warehouse + if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) { + if (! $idwarehouse || $idwarehouse == - 1) { + $error ++; + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action = ''; + } + } + + if (! $error) + { + $result = $object->validate($user, '', $idwarehouse); + if ($result >= 0) + { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } else { + if (count($object->errors)) setEventMessage($object->errors, 'errors'); + else setEventMessage($object->error, 'errors'); + } + } + } + + // Go back to draft status (unvalidate) + else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) { + $idwarehouse = GETPOST('idwarehouse'); + + $object->fetch($id); + $object->fetch_thirdparty(); + + $qualified_for_stock_change = 0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $qualified_for_stock_change = $object->hasProductsOrServices(2); + } else { + $qualified_for_stock_change = $object->hasProductsOrServices(1); + } + + // Check parameters + if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) { + if (! $idwarehouse || $idwarehouse == - 1) { + $error ++; + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); + $action = ''; + } + } + + if (! $error) { + // On verifie si la facture a des paiements + $sql = 'SELECT pf.amount'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf'; + $sql .= ' WHERE pf.fk_facture = ' . $object->id; + + $result = $db->query($sql); + if ($result) { + $i = 0; + $num = $db->num_rows($result); + + while ($i < $num) { + $objp = $db->fetch_object($result); + $totalpaye += $objp->amount; + $i ++; + } + } else { + dol_print_error($db, ''); + } + + $resteapayer = $object->total_ttc - $totalpaye; + + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + // On verifie si aucun paiement n'a ete effectue + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) { + $result=$object->set_draft($user, $idwarehouse); + if ($result<0) setEventMessage($object->error,'errors'); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } + } + + // Classify "paid" + else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) { + $object->fetch($id); + $result = $object->set_paid($user); + if ($result<0) setEventMessage($object->error,'errors'); + } // Classif "paid partialy" + else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) { + $object->fetch($id); + $close_code = $_POST["close_code"]; + $close_note = $_POST["close_note"]; + if ($close_code) { + $result = $object->set_paid($user, $close_code, $close_note); + if ($result<0) setEventMessage($object->error,'errors'); + } else { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); + } + } // Classify "abandoned" + else if ($action == 'confirm_canceled' && $confirm == 'yes') { + $object->fetch($id); + $close_code = $_POST["close_code"]; + $close_note = $_POST["close_note"]; + if ($close_code) { + $result = $object->set_canceled($user, $close_code, $close_note); + if ($result<0) setEventMessage($object->error,'errors'); + } else { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); + } + } + + // Convertir en reduc + else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->fetch_thirdparty(); + //$object->fetch_lines(); // Already done into fetch + + // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) + $discountcheck=new DiscountAbsolute($db); + $result=$discountcheck->fetch(0,$object->id); + + $canconvert=0; + if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if ($canconvert) + { + $db->begin(); + + // Boucle sur chaque taux de tva + $i = 0; + foreach ($object->lines as $line) { + $amount_ht [$line->tva_tx] += $line->total_ht; + $amount_tva [$line->tva_tx] += $line->total_tva; + $amount_ttc [$line->tva_tx] += $line->total_ttc; + $i ++; + } + + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($db); + if ($object->type == Facture::TYPE_CREDIT_NOTE) + $discount->description = '(CREDIT_NOTE)'; + elseif ($object->type == Facture::TYPE_DEPOSIT) + $discount->description = '(DEPOSIT)'; + else { + setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors'); + } + $discount->tva_tx = abs($object->total_ttc); + $discount->fk_soc = $object->socid; + $discount->fk_facture_source = $object->id; + + $error = 0; + foreach ($amount_ht as $tva_tx => $xxx) { + $discount->amount_ht = abs($amount_ht [$tva_tx]); + $discount->amount_tva = abs($amount_tva [$tva_tx]); + $discount->amount_ttc = abs($amount_ttc [$tva_tx]); + $discount->tva_tx = abs($tva_tx); + + $result = $discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } + + if (empty($error)) + { + // Classe facture + $result = $object->set_paid($user); + if ($result >= 0) + { + //$mesgs[]='OK'.$discount->id; + $db->commit(); + } + else + { + setEventMessage($object->error,'errors'); + $db->rollback(); + } + } + else + { + setEventMessage($discount->error,'errors'); + $db->rollback(); + } + } + } + + /* + * Insert new invoice in database + */ + else if ($action == 'add' && $user->rights->facture->creer) + { + if ($socid > 0) $object->socid = GETPOST('socid', 'int'); + + $db->begin(); + + $error = 0; + + // Fill array 'array_options' with data from add form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error ++; + + // Replacement invoice + if ($_POST['type'] == Facture::TYPE_REPLACEMENT) + { + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! ($_POST['fac_replacement'] > 0)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors'); + } + + if (! $error) { + // This is a replacement invoice + $result = $object->fetch($_POST['fac_replacement']); + $object->fetch_thirdparty(); + + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = $_POST['cond_reglement_id']; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + // Proprietes particulieres a facture de remplacement + $object->fk_facture_source = $_POST['fac_replacement']; + $object->type = Facture::TYPE_REPLACEMENT; + + $id = $object->createFromCurrent($user); + if ($id <= 0) + $mesgs [] = $object->error; + } + } + + // Credit note invoice + if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE) + { + if (! ($_POST['fac_avoir'] > 0)) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors'); + } + + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors'); + } + + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = 0; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + // Proprietes particulieres a facture avoir + $object->fk_facture_source = $_POST['fac_avoir']; + $object->type = Facture::TYPE_CREDIT_NOTE; + + $id = $object->create($user); + + if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0) + { + $facture_source = new Facture($db); // fetch origin object + if ($facture_source->fetch($object->fk_facture_source)>0) + { + + foreach($facture_source->lines as $line) + { + $line->fk_facture = $object->id; + + $line->subprice =-$line->subprice; // invert price for object + $line->pa_ht = -$line->pa_ht; + $line->total_ht=-$line->total_ht; + $line->total_tva=-$line->total_tva; + $line->total_ttc=-$line->total_ttc; + $line->total_localtax1=-$line->total_localtax1; + $line->total_localtax2=-$line->total_localtax2; + + $line->insert(); + + $object->lines[] = $line; // insert new line in current object + } + + $object->update_price(1); + } + + } + + if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) { + + $facture_source = new Facture($db); // fetch origin object if not previously defined + if($facture_source->fetch($object->fk_facture_source)>0) { + $totalpaye = $facture_source->getSommePaiement(); + $totalcreditnotes = $facture_source->getSumCreditNotesUsed(); + $totaldeposits = $facture_source->getSumDepositsUsed(); + $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits); + + $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC'); + } + } + + // Add predefined lines + /* + TODO delete + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST['idprod' . $i]) { + $product = new Product($db); + $product->fetch($_POST['idprod' . $i]); + $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); + $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); + $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + }*/ + } + } + + // Standard invoice or Deposit invoice created from a Predefined invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) + { + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->type = $_POST['type']; + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + + // Source facture + $object->fac_rec = $_POST['fac_rec']; + + $id = $object->create($user); + } + } + + // Standard or deposit or proforma invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) + { + if (GETPOST('socid', 'int') < 1) + { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + } + + $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($dateinvoice)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } + + if (! $error) + { + // Si facture standard + $object->socid = GETPOST('socid','int'); + $object->type = GETPOST('type'); + $object->number = $_POST['facnumber']; + $object->date = $dateinvoice; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->amount = $_POST['amount']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + + $object->fetch_thirdparty(); + + // If creation from another object of another module (Example: origin=propal, originid=1) + if ($_POST['origin'] && $_POST['originid']) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $_POST['origin']; + if (preg_match('/^([^_]+)_([^_]+)/i', $_POST['origin'], $regs)) { + $element = $regs [1]; + $subelement = $regs [2]; + } + + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; + $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'inter') { + $element = $subelement = 'ficheinter'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + $object->origin = $_POST['origin']; + $object->origin_id = $_POST['originid']; + + // Possibility to add external linked objects with hooks + $object->linked_objects [$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + $id = $object->create($user); + + if ($id > 0) + { + // If deposit invoice + if ($_POST['type'] == 3) + { + $typeamount = GETPOST('typedeposit', 'alpha'); + $valuedeposit = GETPOST('valuedeposit', 'int'); + + if ($typeamount == 'amount') + { + $amountdeposit = $valuedeposit; + } + else + { + $amountdeposit = 0; + + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) + { + $totalamount = 0; + $lines = $srcobject->lines; + $numlines=count($lines); + for ($i=0; $i<$numlines; $i++) + { + $qualified=1; + if (empty($lines[$i]->qty)) $qualified=0; // We discard qty=0, it is an option + if (! empty($lines[$i]->special_code)) $qualified=0; // We discard special_code (frais port, ecotaxe, option, ...) + if ($qualified) $totalamount += $lines[$i]->total_ht; + } + + if ($totalamount != 0) { + $amountdeposit = ($totalamount * $valuedeposit) / 100; + } + } else { + $mesgs [] = $srcobject->error; + $error ++; + } + } + + $result = $object->addline( + $langs->trans('Deposit'), + $amountdeposit, // subprice + 1, // quantity + $lines [$i]->tva_tx, 0, // localtax1_tx + 0, // localtax2_tx + 0, // fk_product + 0, // remise_percent + 0, // date_start + 0, // date_end + 0, $lines [$i]->info_bits, // info_bits + 0, // info_bits + 'HT', + 0, + 0, // product_type + 1, + $lines [$i]->special_code, + $object->origin, + 0, + 0, + 0, + 0, + $langs->trans('Deposit') + ); + } + else + { + + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + for ($i=0;$i<$num;$i++) + { + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + + if ($lines [$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc = $object->socid; + $discount->amount_ht = abs($lines [$i]->total_ht); + $discount->amount_tva = abs($lines [$i]->total_tva); + $discount->amount_ttc = abs($lines [$i]->total_ttc); + $discount->tva_tx = $lines [$i]->tva_tx; + $discount->fk_user = $user->id; + $discount->description = $desc; + $discountid = $discount->create($user); + if ($discountid > 0) { + $result = $object->insert_discount($discountid); // This include link_to_invoice + } else { + $mesgs [] = $discount->error; + $error ++; + break; + } + } else { + // Positive line + $product_type = ($lines [$i]->product_type ? $lines [$i]->product_type : 0); + + // Date start + $date_start = false; + if ($lines [$i]->date_debut_prevue) + $date_start = $lines [$i]->date_debut_prevue; + if ($lines [$i]->date_debut_reel) + $date_start = $lines [$i]->date_debut_reel; + if ($lines [$i]->date_start) + $date_start = $lines [$i]->date_start; + + // Date end + $date_end = false; + if ($lines [$i]->date_fin_prevue) + $date_end = $lines [$i]->date_fin_prevue; + if ($lines [$i]->date_fin_reel) + $date_end = $lines [$i]->date_fin_reel; + if ($lines [$i]->date_end) + $date_end = $lines [$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) { + $lines [$i]->fetch_optionals($lines [$i]->rowid); + $array_option = $lines [$i]->array_options; + } + + $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $date_start, $date_end, 0, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $object->origin, $lines [$i]->rowid, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); + + if ($result > 0) { + $lineid = $result; + } else { + $lineid = 0; + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines [$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) + $error ++; + } else { + $mesgs [] = $srcobject->error; + $error ++; + } + } + } else { + $mesgs [] = $object->error; + $error ++; + } + } // If some invoice's lines already known + else { + $id = $object->create($user); + + for($i = 1; $i <= $NBLINES; $i ++) { + if ($_POST['idprod' . $i]) { + $product = new Product($db); + $product->fetch($_POST['idprod' . $i]); + $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); + $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); + $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } + } + + // End of object creation, we show it + if ($id > 0 && ! $error) + { + $db->commit(); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + exit(); + } + else + { + $db->rollback(); + $action = 'create'; + $_GET ["origin"] = $_POST["origin"]; + $_GET ["originid"] = $_POST["originid"]; + $mesgs [] = '
' . $object->error . '
'; + } + } + + // Add a new line + else if ($action == 'addline' && $user->rights->facture->creer) + { + $langs->load('errors'); + $error = 0; + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key . $predef]); + } + } + + if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error ++; + } + if ($qty == '') { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error ++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error ++; + } + + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + $ret = $object->fetch($id); + if ($ret < 0) { + dol_print_error($db, $object->error); + exit(); + } + $ret = $object->fetch_thirdparty(); + + // Clean parameters + $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); + $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); + + // Define special_code for special lines + $special_code = 0; + // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if (! empty($idprod)) { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); + + // Update if prices fields are defined + $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); + + // We define price for product + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + { + $pu_ht = $prod->multiprices[$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; + $price_min = $prod->multiprices_min[$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; + if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result >= 0) { + if (count($prodcustprice->lines) > 0) { + $found = true; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; + }else { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + } else { + setEventMessage($prodcustprice->error,'errors'); + } + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + elseif ($tva_tx != $prod->tva_tx) { + if ($price_base_type != 'HT') { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); + } else { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + } + + $desc = ''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if (empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; + } else { + $desc = $prod->description; + } + + $desc = dol_concatdesc($desc, $product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + $tmptxt = '('; + if (! empty($prod->customcode)) + $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) + $tmptxt .= ' - '; + if (! empty($prod->country_code)) + $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); + $tmptxt .= ')'; + $desc = dol_concatdesc($desc, $tmptxt); + } + + $type = $prod->type; + } else { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->client); + $localtax2_tx = get_localtax($tva_tx, 2, $object->client); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); + + if ($result > 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = GETPOST('lang_id', 'alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST ['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); + } else { + setEventMessage($object->error, 'errors'); + } + + $action = ''; + } + } + } + + elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) { + if (! $object->fetch($id) > 0) + dol_print_error($db); + $object->fetch_thirdparty(); + + // Clean parameters + $date_start = ''; + $date_end = ''; + $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht = GETPOST('price_ht'); + $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + + // Define info_bits + $info_bits = 0; + if (preg_match('/\*/', $vat_rate)) + $info_bits |= 0x01; + + // Define vat_rate + $vat_rate = str_replace('*', '', $vat_rate); + $localtax1_rate = get_localtax($vat_rate, 1, $object->client); + $localtax2_rate = get_localtax($vat_rate, 2, $object->client); + + // Add buying price + $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) { + $product = new Product($db); + $product->fetch($productid); + + $type = $product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min [$object->client->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); + + // Check price is not lower than minimum (check is done only for standard or replacement invoices) + if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + $error ++; + } + } else { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + } + + // Update line + if (! $error) { + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); + + if ($result >= 0) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) + $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['productid']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + } else { + setEventMessage($object->error, 'errors'); + } + } + } + + else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition exit(); - } else { - setEventMessage($object->error, 'errors'); - $action=''; } -} -// Delete line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); + // Modify line position (up) + else if ($action == 'up' && $user->rights->facture->creer) { + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_up($_GET ['rowid']); - $result = $object->deleteline($_GET ['lineid'], $user); - if ($result > 0) { // Define output language $outputlangs = $langs; $newlang = ''; @@ -187,1626 +1458,358 @@ else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights-> $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($id); // Reload to get new records - $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); + exit(); + } // Modify line position (down) + else if ($action == 'down' && $user->rights->facture->creer) { + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_down($_GET ['rowid']); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->client->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); } - if ($result >= 0) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); - exit(); - } - } else { - setEventMessage($object->error, 'errors'); - $action = ''; - } -} + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); -// Delete link of credit note to invoice -else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) { - $discount = new DiscountAbsolute($db); - $result = $discount->fetch($_GET ["discountid"]); - $discount->unlink_invoice(); -} - -// Validation -else if ($action == 'valid' && $user->rights->facture->creer) { - $object->fetch($id); - - // On verifie signe facture - if ($object->type == Facture::TYPE_CREDIT_NOTE) { - // Si avoir, le signe doit etre negatif - if ($object->total_ht >= 0) { - $mesgs [] = '
' . $langs->trans("ErrorInvoiceAvoirMustBeNegative") . '
'; - $action = ''; - } - } else { - // Si non avoir, le signe doit etre positif - if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) { - $mesgs [] = '
' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive") . '
'; - $action = ''; - } - } -} - -else if ($action == 'set_thirdparty' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setValueFrom('fk_soc', $socid); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); - exit(); -} - -else if ($action == 'classin' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setProject($_POST['projectid']); -} - -else if ($action == 'setmode' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setinvoicedate' && $user->rights->facture->creer) -{ - $object->fetch($id); - $old_date_lim_reglement = $object->date_lim_reglement; - $date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']); - if (empty($date)) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate'); - exit; - } - $object->date=$date; - $new_date_lim_reglement = $object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; - $result = $object->update($user); - if ($result < 0) dol_print_error($db, $object->error); -} - -else if ($action == 'setconditions' && $user->rights->facture->creer) { - $object->fetch($id); - $object->cond_reglement_code = 0; // To clean property - $object->cond_reglement_id = 0; // To clean property - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); - if ($result < 0) dol_print_error($db, $object->error); - - $old_date_lim_reglement = $object->date_lim_reglement; - $new_date_lim_reglement = $object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date; - $result = $object->update($user); - if ($result < 0) dol_print_error($db, $object->error); -} - -else if ($action == 'setpaymentterm' && $user->rights->facture->creer) { - $object->fetch($id); - $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']); - if ($object->date_lim_reglement < $object->date) { - $object->date_lim_reglement = $object->calculate_date_lim_reglement(); - setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), 'warnings'); - } - $result = $object->update($user); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) { - $object->fetch($id); - $object->revenuestamp = GETPOST('revenuestamp'); - $result = $object->update($user); - $object->update_price(1); - if ($result < 0) - dol_print_error($db, $object->error); -} - -else if ($action == 'setremisepercent' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->set_remise($user, $_POST['remise_percent']); -} - -else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { - // POST[remise_id] ou POST[remise_id_for_payment] - if (! empty($_POST["remise_id"])) { - $ret = $object->fetch($id); - if ($ret > 0) { - $result = $object->insert_discount($_POST["remise_id"]); - if ($result < 0) { - $mesgs [] = '
' . $object->error . '
'; - } - } else { - dol_print_error($db, $object->error); - } - } - if (! empty($_POST["remise_id_for_payment"])) { - require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; - $discount = new DiscountAbsolute($db); - $discount->fetch($_POST["remise_id_for_payment"]); - - $result = $discount->link_to_invoice(0, $id); - if ($result < 0) { - $mesgs [] = '
' . $discount->error . '
'; - } - } -} - -else if ($action == 'set_ref_client' && $user->rights->facture->creer) { - $object->fetch($id); - $object->set_ref_client($_POST['ref_client']); -} - -// Classify to validated -else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) -{ - $idwarehouse = GETPOST('idwarehouse'); - - $object->fetch($id); - $object->fetch_thirdparty(); - - // Check parameters - - // Check for mandatory prof id - for($i = 1; $i < 6; $i ++) - { - $idprof_mandatory = 'SOCIETE_IDPROF' . ($i) . '_INVOICE_MANDATORY'; - $idprof = 'idprof' . $i; - if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) { - if (! $error) - $langs->load("errors"); - $error ++; - - setEventMessage($langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId' . $i, $object->thirdparty->country_code)), 'errors'); - } - } - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); - } - - // Check for warehouse - if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) { - if (! $idwarehouse || $idwarehouse == - 1) { - $error ++; - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action = ''; - } - } - - if (! $error) - { - $result = $object->validate($user, '', $idwarehouse); - if ($result >= 0) - { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } else { - if (count($object->errors)) setEventMessage($object->errors, 'errors'); - else setEventMessage($object->error, 'errors'); - } - } -} - -// Go back to draft status (unvalidate) -else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) { - $idwarehouse = GETPOST('idwarehouse'); - - $object->fetch($id); - $object->fetch_thirdparty(); - - $qualified_for_stock_change = 0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $qualified_for_stock_change = $object->hasProductsOrServices(2); - } else { - $qualified_for_stock_change = $object->hasProductsOrServices(1); - } - - // Check parameters - if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) { - if (! $idwarehouse || $idwarehouse == - 1) { - $error ++; - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), 'errors'); - $action = ''; - } - } - - if (! $error) { - // On verifie si la facture a des paiements - $sql = 'SELECT pf.amount'; - $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf'; - $sql .= ' WHERE pf.fk_facture = ' . $object->id; - - $result = $db->query($sql); - if ($result) { - $i = 0; - $num = $db->num_rows($result); - - while ($i < $num) { - $objp = $db->fetch_object($result); - $totalpaye += $objp->amount; - $i ++; - } - } else { - dol_print_error($db, ''); - } - - $resteapayer = $object->total_ttc - $totalpaye; - - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); - - // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) { - $result=$object->set_draft($user, $idwarehouse); - if ($result<0) setEventMessage($object->error,'errors'); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $ret = $object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - } -} - -// Classify "paid" -else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $result = $object->set_paid($user); - if ($result<0) setEventMessage($object->error,'errors'); -} // Classif "paid partialy" -else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $close_code = $_POST["close_code"]; - $close_note = $_POST["close_note"]; - if ($close_code) { - $result = $object->set_paid($user, $close_code, $close_note); - if ($result<0) setEventMessage($object->error,'errors'); - } else { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); - } -} // Classify "abandoned" -else if ($action == 'confirm_canceled' && $confirm == 'yes') { - $object->fetch($id); - $close_code = $_POST["close_code"]; - $close_note = $_POST["close_note"]; - if ($close_code) { - $result = $object->set_canceled($user, $close_code, $close_note); - if ($result<0) setEventMessage($object->error,'errors'); - } else { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors'); - } -} - -// Convertir en reduc -else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) -{ - $object->fetch($id); - $object->fetch_thirdparty(); - //$object->fetch_lines(); // Already done into fetch - - // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) - $discountcheck=new DiscountAbsolute($db); - $result=$discountcheck->fetch(0,$object->id); - - $canconvert=0; - if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) - if ($canconvert) - { - $db->begin(); - - // Boucle sur chaque taux de tva - $i = 0; - foreach ($object->lines as $line) { - $amount_ht [$line->tva_tx] += $line->total_ht; - $amount_tva [$line->tva_tx] += $line->total_tva; - $amount_ttc [$line->tva_tx] += $line->total_ttc; - $i ++; - } - - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($db); - if ($object->type == Facture::TYPE_CREDIT_NOTE) - $discount->description = '(CREDIT_NOTE)'; - elseif ($object->type == Facture::TYPE_DEPOSIT) - $discount->description = '(DEPOSIT)'; - else { - setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors'); - } - $discount->tva_tx = abs($object->total_ttc); - $discount->fk_soc = $object->socid; - $discount->fk_facture_source = $object->id; - - $error = 0; - foreach ($amount_ht as $tva_tx => $xxx) { - $discount->amount_ht = abs($amount_ht [$tva_tx]); - $discount->amount_tva = abs($amount_tva [$tva_tx]); - $discount->amount_ttc = abs($amount_ttc [$tva_tx]); - $discount->tva_tx = abs($tva_tx); - - $result = $discount->create($user); - if ($result < 0) - { - $error++; - break; - } - } - - if (empty($error)) - { - // Classe facture - $result = $object->set_paid($user); - if ($result >= 0) - { - //$mesgs[]='OK'.$discount->id; - $db->commit(); - } - else - { - setEventMessage($object->error,'errors'); - $db->rollback(); - } - } - else - { - setEventMessage($discount->error,'errors'); - $db->rollback(); - } - } -} - -/* - * Insert new invoice in database -*/ -else if ($action == 'add' && $user->rights->facture->creer) -{ - if ($socid > 0) $object->socid = GETPOST('socid', 'int'); - - $db->begin(); - - $error = 0; - - // Fill array 'array_options' with data from add form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) $error ++; - - // Replacement invoice - if ($_POST['type'] == Facture::TYPE_REPLACEMENT) - { - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! ($_POST['fac_replacement'] > 0)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors'); - } - - if (! $error) { - // This is a replacement invoice - $result = $object->fetch($_POST['fac_replacement']); - $object->fetch_thirdparty(); - - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = $_POST['cond_reglement_id']; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - // Proprietes particulieres a facture de remplacement - $object->fk_facture_source = $_POST['fac_replacement']; - $object->type = Facture::TYPE_REPLACEMENT; - - $id = $object->createFromCurrent($user); - if ($id <= 0) - $mesgs [] = $object->error; - } - } - - // Credit note invoice - if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE) - { - if (! ($_POST['fac_avoir'] > 0)) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors'); - } - - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors'); - } - - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = 0; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - // Proprietes particulieres a facture avoir - $object->fk_facture_source = $_POST['fac_avoir']; - $object->type = Facture::TYPE_CREDIT_NOTE; - - $id = $object->create($user); - - if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0) - { - $facture_source = new Facture($db); // fetch origin object - if ($facture_source->fetch($object->fk_facture_source)>0) - { - - foreach($facture_source->lines as $line) - { - $line->fk_facture = $object->id; - - $line->subprice =-$line->subprice; // invert price for object - $line->pa_ht = -$line->pa_ht; - $line->total_ht=-$line->total_ht; - $line->total_tva=-$line->total_tva; - $line->total_ttc=-$line->total_ttc; - $line->total_localtax1=-$line->total_localtax1; - $line->total_localtax2=-$line->total_localtax2; - - $line->insert(); - - $object->lines[] = $line; // insert new line in current object - } - - $object->update_price(1); - } - - } - - if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) { - - $facture_source = new Facture($db); // fetch origin object if not previously defined - if($facture_source->fetch($object->fk_facture_source)>0) { - $totalpaye = $facture_source->getSommePaiement(); - $totalcreditnotes = $facture_source->getSumCreditNotesUsed(); - $totaldeposits = $facture_source->getSumDepositsUsed(); - $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits); - - $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC'); - } - } - - // Add predefined lines - /* - TODO delete - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST['idprod' . $i]) { - $product = new Product($db); - $product->fetch($_POST['idprod' . $i]); - $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); - $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); - $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - }*/ - } - } - - // Standard invoice or Deposit invoice created from a Predefined invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) - { - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->type = $_POST['type']; - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - - // Source facture - $object->fac_rec = $_POST['fac_rec']; - - $id = $object->create($user); - } - } - - // Standard or deposit or proforma invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) - { - if (GETPOST('socid', 'int') < 1) - { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); - } - - $dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($dateinvoice)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - - if (! $error) - { - // Si facture standard - $object->socid = GETPOST('socid','int'); - $object->type = GETPOST('type'); - $object->number = $_POST['facnumber']; - $object->date = $dateinvoice; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->amount = $_POST['amount']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - - $object->fetch_thirdparty(); - - // If creation from another object of another module (Example: origin=propal, originid=1) - if ($_POST['origin'] && $_POST['originid']) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $_POST['origin']; - if (preg_match('/^([^_]+)_([^_]+)/i', $_POST['origin'], $regs)) { - $element = $regs [1]; - $subelement = $regs [2]; - } - - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; - $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - if ($element == 'inter') { - $element = $subelement = 'ficheinter'; - } - if ($element == 'shipping') { - $element = $subelement = 'expedition'; - } - - $object->origin = $_POST['origin']; - $object->origin_id = $_POST['originid']; - - // Possibility to add external linked objects with hooks - $object->linked_objects [$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } - - $id = $object->create($user); - - if ($id > 0) - { - // If deposit invoice - if ($_POST['type'] == 3) - { - $typeamount = GETPOST('typedeposit', 'alpha'); - $valuedeposit = GETPOST('valuedeposit', 'int'); - - if ($typeamount == 'amount') - { - $amountdeposit = $valuedeposit; - } - else - { - $amountdeposit = 0; - - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) - { - $totalamount = 0; - $lines = $srcobject->lines; - $numlines=count($lines); - for ($i=0; $i<$numlines; $i++) - { - $qualified=1; - if (empty($lines[$i]->qty)) $qualified=0; // We discard qty=0, it is an option - if (! empty($lines[$i]->special_code)) $qualified=0; // We discard special_code (frais port, ecotaxe, option, ...) - if ($qualified) $totalamount += $lines[$i]->total_ht; - } - - if ($totalamount != 0) { - $amountdeposit = ($totalamount * $valuedeposit) / 100; - } - } else { - $mesgs [] = $srcobject->error; - $error ++; - } - } - - $result = $object->addline( - $langs->trans('Deposit'), - $amountdeposit, // subprice - 1, // quantity - $lines [$i]->tva_tx, 0, // localtax1_tx - 0, // localtax2_tx - 0, // fk_product - 0, // remise_percent - 0, // date_start - 0, // date_end - 0, $lines [$i]->info_bits, // info_bits - 0, // info_bits - 'HT', - 0, - 0, // product_type - 1, - $lines [$i]->special_code, - $object->origin, - 0, - 0, - 0, - 0, - $langs->trans('Deposit') - ); - } - else - { - - dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); - $result = $srcobject->fetch($object->origin_id); - if ($result > 0) - { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject, 'fetch_lines')) - { - $srcobject->fetch_lines(); - $lines = $srcobject->lines; - } - - $fk_parent_line=0; - $num=count($lines); - for ($i=0;$i<$num;$i++) - { - $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); - $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); - - if ($lines [$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc = $object->socid; - $discount->amount_ht = abs($lines [$i]->total_ht); - $discount->amount_tva = abs($lines [$i]->total_tva); - $discount->amount_ttc = abs($lines [$i]->total_ttc); - $discount->tva_tx = $lines [$i]->tva_tx; - $discount->fk_user = $user->id; - $discount->description = $desc; - $discountid = $discount->create($user); - if ($discountid > 0) { - $result = $object->insert_discount($discountid); // This include link_to_invoice - } else { - $mesgs [] = $discount->error; - $error ++; - break; - } - } else { - // Positive line - $product_type = ($lines [$i]->product_type ? $lines [$i]->product_type : 0); - - // Date start - $date_start = false; - if ($lines [$i]->date_debut_prevue) - $date_start = $lines [$i]->date_debut_prevue; - if ($lines [$i]->date_debut_reel) - $date_start = $lines [$i]->date_debut_reel; - if ($lines [$i]->date_start) - $date_start = $lines [$i]->date_start; - - // Date end - $date_end = false; - if ($lines [$i]->date_fin_prevue) - $date_end = $lines [$i]->date_fin_prevue; - if ($lines [$i]->date_fin_reel) - $date_end = $lines [$i]->date_fin_reel; - if ($lines [$i]->date_end) - $date_end = $lines [$i]->date_end; - - // Reset fk_parent_line for no child products and special product - if (($lines [$i]->product_type != 9 && empty($lines [$i]->fk_parent_line)) || $lines [$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) { - $lines [$i]->fetch_optionals($lines [$i]->rowid); - $array_option = $lines [$i]->array_options; - } - - $result = $object->addline($desc, $lines [$i]->subprice, $lines [$i]->qty, $lines [$i]->tva_tx, $lines [$i]->localtax1_tx, $lines [$i]->localtax2_tx, $lines [$i]->fk_product, $lines [$i]->remise_percent, $date_start, $date_end, 0, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $object->origin, $lines [$i]->rowid, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option); - - if ($result > 0) { - $lineid = $result; - } else { - $lineid = 0; - $error ++; - break; - } - - // Defined the new fk_parent_line - if ($result > 0 && $lines [$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } - - // Hooks - $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) - $error ++; - } else { - $mesgs [] = $srcobject->error; - $error ++; - } - } - } else { - $mesgs [] = $object->error; - $error ++; - } - } // If some invoice's lines already known - else { - $id = $object->create($user); - - for($i = 1; $i <= $NBLINES; $i ++) { - if ($_POST['idprod' . $i]) { - $product = new Product($db); - $product->fetch($_POST['idprod' . $i]); - $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']); - $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']); - $result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } - } - - // End of object creation, we show it - if ($id > 0 && ! $error) - { - $db->commit(); - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); exit(); } - else - { - $db->rollback(); - $action = 'create'; - $_GET ["origin"] = $_POST["origin"]; - $_GET ["originid"] = $_POST["originid"]; - $mesgs [] = '
' . $object->error . '
'; - } -} -// Add a new line -else if ($action == 'addline' && $user->rights->facture->creer) -{ - $langs->load('errors'); - $error = 0; - - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - $price_ht = GETPOST('price_ht'); - if (GETPOST('prod_entry_mode') == 'free') - { - $idprod=0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $tva_tx = ''; + // Link invoice to order + if (GETPOST('linkedOrder')) { + $object->fetch($id); + $object->fetch_thirdparty(); + $result = $object->add_object_linked('commande', GETPOST('linkedOrder')); } - $qty = GETPOST('qty' . $predef); - $remise_percent = GETPOST('remise_percent' . $predef); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key . $predef]); - } - } - - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; - } - if ($qty == '') { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error ++; - } - - if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { - $ret = $object->fetch($id); - if ($ret < 0) { - dol_print_error($db, $object->error); - exit(); - } - $ret = $object->fetch_thirdparty(); - - // Clean parameters - $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year')); - $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); - - // Define special_code for special lines - $special_code = 0; - // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); - - // Update if prices fields are defined - $tva_tx = get_default_tva($mysoc, $object->client, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->client, $prod->id); - - // We define price for product - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - { - $pu_ht = $prod->multiprices[$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; - $price_min = $prod->multiprices_min[$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; - if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level]; - if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result >= 0) { - if (count($prodcustprice->lines) > 0) { - $found = true; - $pu_ht = price($prodcustprice->lines[0]->price); - $pu_ttc = price($prodcustprice->lines[0]->price_ttc); - $price_base_type = $prodcustprice->lines[0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; - }else { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } - } else { - setEventMessage($prodcustprice->error,'errors'); - } - } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } - - // if price ht is forced (ie: calculated by margin rate and cost price) - if (! empty($price_ht)) { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - elseif ($tva_tx != $prod->tva_tx) { - if ($price_base_type != 'HT') { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); - } else { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); - } - } - - $desc = ''; - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if (empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description; - } else { - $desc = $prod->description; - } - - $desc = dol_concatdesc($desc, $product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { - $tmptxt = '('; - if (! empty($prod->customcode)) - $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) - $tmptxt .= ' - '; - if (! empty($prod->country_code)) - $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0); - $tmptxt .= ')'; - $desc = dol_concatdesc($desc, $tmptxt); - } - - $type = $prod->type; - } else { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - $desc = $product_desc; - $type = GETPOST('type'); - } - - // Margin - $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); - $buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->client); - $localtax2_tx = get_localtax($tva_tx, 2, $object->client); - - $info_bits = 0; - if ($tva_npr) - $info_bits |= 0x01; - - if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { - $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); - } else { - // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); - - if ($result > 0) { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = GETPOST('lang_id', 'alpha'); - if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST ['prod_entry_mode']); - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - unset($_POST['np_marginRate']); - unset($_POST['np_markRate']); - unset($_POST['dp_desc']); - unset($_POST['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); - } else { - setEventMessage($object->error, 'errors'); - } - - $action = ''; - } - } -} - -elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) { - if (! $object->fetch($id) > 0) - dol_print_error($db); - $object->fetch_thirdparty(); - - // Clean parameters - $date_start = ''; - $date_end = ''; - $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht = GETPOST('price_ht'); - $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - - // Define info_bits - $info_bits = 0; - if (preg_match('/\*/', $vat_rate)) - $info_bits |= 0x01; - - // Define vat_rate - $vat_rate = str_replace('*', '', $vat_rate); - $localtax1_rate = get_localtax($vat_rate, 1, $object->client); - $localtax2_rate = get_localtax($vat_rate, 2, $object->client); - - // Add buying price - $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); - $buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : ''); - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } - } - - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) { - $product = new Product($db); - $product->fetch($productid); - - $type = $product->type; - - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min [$object->client->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); - - // Check price is not lower than minimum (check is done only for standard or replacement invoices) - if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; - } - } else { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); - - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; - } - } - - // Update line - if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); - - if ($result >= 0) { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) - $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['productid']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - } else { - setEventMessage($object->error, 'errors'); - } - } -} - -else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition - exit(); -} - -// Modify line position (up) -else if ($action == 'up' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_up($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); -} // Modify line position (down) -else if ($action == 'down' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_down($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->client->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); -} - -// Link invoice to order -if (GETPOST('linkedOrder')) { - $object->fetch($id); - $object->fetch_thirdparty(); - $result = $object->add_object_linked('commande', GETPOST('linkedOrder')); -} - -/* - * Add file in email form - */ -if (GETPOST('addfile')) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; - - dol_add_file_process($upload_dir_tmp, 0, 0); - $action = 'presend'; -} - -/* - * Remove file in email form - */ -if (! empty($_POST['removedfile'])) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir = $conf->user->dir_output . "/" . $user->id; - $upload_dir_tmp = $vardir . '/temp'; - - // TODO Delete only files that was uploaded from email form - dol_remove_file_process($_POST['removedfile'], 0); - $action = 'presend'; -} - -/* - * Send mail - */ -if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) { - $langs->load('mails'); - - $actiontypecode = ''; - $subject = ''; - $actionmsg = ''; - $actionmsg2 = ''; - - $result = $object->fetch($id); - $result = $object->fetch_thirdparty(); - - if ($result > 0) { - // $ref = dol_sanitizeFileName($object->ref); - // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; - - // if (is_readable($file)) - // { - if ($_POST['sendto']) { - // Le destinataire a ete fourni via le champ libre - $sendto = $_POST['sendto']; - $sendtoid = 0; - } elseif ($_POST['receiver'] != '-1') { - // Recipient was provided from combo list - if ($_POST['receiver'] == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } else // Id du contact - { - $sendto = $object->client->contact_get_property($_POST['receiver'], 'email'); - $sendtoid = $_POST['receiver']; - } - } - - if (dol_strlen($sendto)) { - $langs->load("commercial"); - - $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>'; - $replyto = $_POST['replytoname'] . ' <' . $_POST['replytomail'] . '>'; - $message = $_POST['message']; - $sendtocc = $_POST['sendtocc']; - $deliveryreceipt = $_POST['deliveryreceipt']; - - if ($action == 'send') { - if (dol_strlen($_POST['subject'])) - $subject = $_POST['subject']; - else - $subject = $langs->transnoentities('Bill') . ' ' . $object->ref; - $actiontypecode = 'AC_FAC'; - $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; - if ($message) { - $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; - $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; - $actionmsg .= $message; - } - // $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - if ($action == 'relance') { - if (dol_strlen($_POST['subject'])) - $subject = $_POST['subject']; - else - $subject = $langs->transnoentities('Relance facture ' . $object->ref); - $actiontypecode = 'AC_FAC'; - $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; - if ($message) { - $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; - $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; - $actionmsg .= $message; - } - // $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - - // Create form object - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles = $formmail->get_attached_files(); - $filepath = $attachedfiles ['paths']; - $filename = $attachedfiles ['names']; - $mimetype = $attachedfiles ['mimes']; - - // Send mail - require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); - if ($mailfile->error) { - $mesgs [] = '
' . $mailfile->error . '
'; - } else { - $result = $mailfile->sendfile(); - if ($result) { - $error = 0; - - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; // Long text - $object->actionmsg2 = $actionmsg2; // Short text - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface = new Interfaces($db); - $result = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf); - if ($result < 0) { - $error++; - $object->errors = $interface->errors; - } - // Fin appel triggers - - if ($error) { - dol_print_error($db); - } else { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); - setEventMessage($mesg); - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id); - exit(); - } - } else { - $langs->load("other"); - $mesg = '
'; - if ($mailfile->error) { - $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); - $mesg .= '
' . $mailfile->error; - } else { - $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - $mesg .= '
'; - $mesgs [] = $mesg; - } - } - /* } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; - dol_syslog('Recipient email is empty'); - }*/ - } else { - $langs->load("errors"); - $mesgs [] = '
' . $langs->trans('ErrorCantReadFile', $file) . '
'; - dol_syslog('Failed to read file: ' . $file); - } - } else { - $langs->load("other"); - $mesgs [] = '
' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Invoice")) . '
'; - dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); - } - - $action = 'presend'; -} - -/* - * Generate document - */ -else if ($action == 'builddoc') // En get ou en post -{ - $object->fetch($id); - $object->fetch_thirdparty(); - - // Save last template used to generate document - if (GETPOST('model')) - $object->setDocModel($user, GETPOST('model', 'alpha')); - if (GETPOST('fk_bank')) // this field may come from an external module - $object->fk_bank = GETPOST('fk_bank'); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db, $result); - exit(); - } -} - -// Remove file in doc form -else if ($action == 'remove_file') { - if ($object->fetch($id)) { + /* + * Add file in email form + */ + if (GETPOST('addfile')) { require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // Set tmp user directory + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; + + dol_add_file_process($upload_dir_tmp, 0, 0); + $action = 'presend'; + } + + /* + * Remove file in email form + */ + if (! empty($_POST['removedfile'])) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir = $conf->user->dir_output . "/" . $user->id; + $upload_dir_tmp = $vardir . '/temp'; + + // TODO Delete only files that was uploaded from email form + dol_remove_file_process($_POST['removedfile'], 0); + $action = 'presend'; + } + + /* + * Send mail + */ + if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) { + $langs->load('mails'); + + $actiontypecode = ''; + $subject = ''; + $actionmsg = ''; + $actionmsg2 = ''; + + $result = $object->fetch($id); + $result = $object->fetch_thirdparty(); + + if ($result > 0) { + // $ref = dol_sanitizeFileName($object->ref); + // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; + + // if (is_readable($file)) + // { + if ($_POST['sendto']) { + // Le destinataire a ete fourni via le champ libre + $sendto = $_POST['sendto']; + $sendtoid = 0; + } elseif ($_POST['receiver'] != '-1') { + // Recipient was provided from combo list + if ($_POST['receiver'] == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } else // Id du contact + { + $sendto = $object->client->contact_get_property($_POST['receiver'], 'email'); + $sendtoid = $_POST['receiver']; + } + } + + if (dol_strlen($sendto)) { + $langs->load("commercial"); + + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>'; + $replyto = $_POST['replytoname'] . ' <' . $_POST['replytomail'] . '>'; + $message = $_POST['message']; + $sendtocc = $_POST['sendtocc']; + $deliveryreceipt = $_POST['deliveryreceipt']; + + if ($action == 'send') { + if (dol_strlen($_POST['subject'])) + $subject = $_POST['subject']; + else + $subject = $langs->transnoentities('Bill') . ' ' . $object->ref; + $actiontypecode = 'AC_FAC'; + $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; + if ($message) { + $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; + $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; + $actionmsg .= $message; + } + // $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + if ($action == 'relance') { + if (dol_strlen($_POST['subject'])) + $subject = $_POST['subject']; + else + $subject = $langs->transnoentities('Relance facture ' . $object->ref); + $actiontypecode = 'AC_FAC'; + $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n"; + if ($message) { + $actionmsg .= $langs->transnoentities('MailTopic') . ": " . $subject . "\n"; + $actionmsg .= $langs->transnoentities('TextUsedInTheMessageBody') . ":\n"; + $actionmsg .= $message; + } + // $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + + // Create form object + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles = $formmail->get_attached_files(); + $filepath = $attachedfiles ['paths']; + $filename = $attachedfiles ['names']; + $mimetype = $attachedfiles ['mimes']; + + // Send mail + require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, - 1); + if ($mailfile->error) { + $mesgs [] = '
' . $mailfile->error . '
'; + } else { + $result = $mailfile->sendfile(); + if ($result) { + $error = 0; + + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; // Long text + $object->actionmsg2 = $actionmsg2; // Short text + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface = new Interfaces($db); + $result = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf); + if ($result < 0) { + $error++; + $object->errors = $interface->errors; + } + // Fin appel triggers + + if ($error) { + dol_print_error($db); + } else { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); + setEventMessage($mesg); + header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id); + exit(); + } + } else { + $langs->load("other"); + $mesg = '
'; + if ($mailfile->error) { + $mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); + $mesg .= '
' . $mailfile->error; + } else { + $mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg .= '
'; + $mesgs [] = $mesg; + } + } + /* } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; + dol_syslog('Recipient email is empty'); + }*/ + } else { + $langs->load("errors"); + $mesgs [] = '
' . $langs->trans('ErrorCantReadFile', $file) . '
'; + dol_syslog('Failed to read file: ' . $file); + } + } else { + $langs->load("other"); + $mesgs [] = '
' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Invoice")) . '
'; + dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); + } + + $action = 'presend'; + } + + /* + * Generate document + */ + else if ($action == 'builddoc') // En get ou en post + { + $object->fetch($id); $object->fetch_thirdparty(); - $langs->load("other"); - $upload_dir = $conf->facture->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + // Save last template used to generate document + if (GETPOST('model')) + $object->setDocModel($user, GETPOST('model', 'alpha')); + if (GETPOST('fk_bank')) // this field may come from an external module + $object->fk_bank = GETPOST('fk_bank'); + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db, $result); + exit(); + } + } + + // Remove file in doc form + else if ($action == 'remove_file') { + if ($object->fetch($id)) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->facture->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) + setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else + setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action = ''; + } + } + + // Print file + else if ($action == 'print_file' and $user->rights->printipp->read) { + require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; + $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); + $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); + setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file'))); $action = ''; } -} -// Print file -else if ($action == 'print_file' and $user->rights->printipp->read) { - require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php'; - $printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD); - $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file'))); - $action = ''; -} + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { + if ($action == 'addcontact') { + $result = $object->fetch($id); -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { - if ($action == 'addcontact') { - $result = $object->fetch($id); + if ($result > 0 && $id > 0) { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + } - if ($result > 0 && $id > 0) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); - } - - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $langs->load("errors"); - $mesgs [] = '
' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '
'; + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); } else { - $mesgs [] = '
' . $object->error . '
'; + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + $mesgs [] = '
' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '
'; + } else { + $mesgs [] = '
' . $object->error . '
'; + } + } + } + + // bascule du statut d'un contact + else if ($action == 'swapstatut') { + if ($object->fetch($id)) { + $result = $object->swapContactStatus(GETPOST('ligne')); + } else { + dol_print_error($db); + } + } + + // Efface un contact + else if ($action == 'deletecontact') { + $object->fetch($id); + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit(); + } else { + dol_print_error($db); } } } - // bascule du statut d'un contact - else if ($action == 'swapstatut') { - if ($object->fetch($id)) { - $result = $object->swapContactStatus(GETPOST('ligne')); - } else { - dol_print_error($db); - } - } - - // Efface un contact - else if ($action == 'deletecontact') { - $object->fetch($id); - $result = $object->delete_contact($lineid); - - if ($result >= 0) { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit(); - } else { - dol_print_error($db); - } - } -} - -if ($action == 'update_extras') { - // Fill array 'array_options' with data from add form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - - if (! $error) { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters = array('id' => $object->id); - $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by - // some hooks - if (empty($reshook)) { - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) + if ($action == 'update_extras') { + // Fill array 'array_options' with data from add form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) $error ++; - } - if ($error) - $action = 'edit_extras'; + if (! $error) { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } } diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 3aafa1c165b..c96ddaa4b9f 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -71,182 +71,184 @@ $hookmanager->initHooks(array('paiementcard')); $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -/* - * Actions - */ -if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) -{ - $error = 0; +if (empty($reshook)) { - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $paiement_id = 0; - $totalpayment = 0; - $atleastonepaymentnotnull = 0; - - // Generate payment array and check if there is payment higher than invoice and payment date before invoice date - $tmpinvoice=new Facture($db); - foreach ($_POST as $key => $value) + /* + * Actions + */ + if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) { - if (substr($key,0,7) == 'amount_') + $error = 0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $paiement_id = 0; + $totalpayment = 0; + $atleastonepaymentnotnull = 0; + + // Generate payment array and check if there is payment higher than invoice and payment date before invoice date + $tmpinvoice=new Facture($db); + foreach ($_POST as $key => $value) { - $cursorfacid = substr($key,7); - $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); - $totalpayment = $totalpayment + $amounts[$cursorfacid]; - if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; - $result=$tmpinvoice->fetch($cursorfacid); - if ($result <= 0) dol_print_error($db); - $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); - if ($amounts[$cursorfacid]) + if (substr($key,0,7) == 'amount_') { - // Check amount - if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) - { - $addwarning=1; - $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay"); - } - // Check date - if ($datepaye && ($datepaye < $tmpinvoice->date)) - { - $langs->load("errors"); - //$error++; - setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); - } - } + $cursorfacid = substr($key,7); + $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); + $totalpayment = $totalpayment + $amounts[$cursorfacid]; + if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; + $result=$tmpinvoice->fetch($cursorfacid); + if ($result <= 0) dol_print_error($db); + $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); + if ($amounts[$cursorfacid]) + { + // Check amount + if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) + { + $addwarning=1; + $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay"); + } + // Check date + if ($datepaye && ($datepaye < $tmpinvoice->date)) + { + $langs->load("errors"); + //$error++; + setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); + } + } - $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); - } - } - - // Check parameters - if (! GETPOST('paiementcode')) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); - $error++; - } - - if (! empty($conf->banque->enabled)) - { - // If bank module is on, account is required to enter a payment - if (GETPOST('accountid') <= 0) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); - $error++; - } - } - - if (empty($totalpayment) && empty($atleastonepaymentnotnull)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); - $error++; - } - - if (empty($datepaye)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); - $error++; - } -} - -/* - * Action add_paiement - */ -if ($action == 'add_paiement') -{ - if ($error) - { - $action = 'create'; - } - // Le reste propre a cette action s'affiche en bas de page. -} - -/* - * Action confirm_paiement - */ -if ($action == 'confirm_paiement' && $confirm == 'yes') -{ - $error=0; - - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - - $db->begin(); - - // Clean parameters amount if payment is for a credit note - if (GETPOST('type') == 2) - { - foreach ($amounts as $key => $value) // How payment is dispatch - { - $newvalue = price2num($value,'MT'); - $amounts[$key] = -$newvalue; - } - } - - if (! empty($conf->banque->enabled)) - { - // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement - if (GETPOST('accountid') <= 0) - { - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); - $error++; - } - } - - // Creation of payment line - $paiement = new Paiement($db); - $paiement->datepaye = $datepaye; - $paiement->amounts = $amounts; // Array with all payments dispatching - $paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement'); - $paiement->num_paiement = $_POST['num_paiement']; - $paiement->note = $_POST['comment']; - - if (! $error) - { - $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0)); - if ($paiement_id < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } - - if (! $error) - { - $label='(CustomerInvoicePayment)'; - if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)'; - $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank')); - if ($result < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } - - if (! $error) - { - $db->commit(); - - // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card - $invoiceid=0; - foreach ($paiement->amounts as $key => $amount) - { - $facid = $key; - if (is_numeric($amount) && $amount <> 0) - { - if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment - else $invoiceid=$facid; + $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); } } - if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid; - else $loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id; - header('Location: '.$loc); - exit; + + // Check parameters + if (! GETPOST('paiementcode')) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); + $error++; + } + + if (! empty($conf->banque->enabled)) + { + // If bank module is on, account is required to enter a payment + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } + + if (empty($totalpayment) && empty($atleastonepaymentnotnull)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); + $error++; + } + + if (empty($datepaye)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); + $error++; + } } - else + + /* + * Action add_paiement + */ + if ($action == 'add_paiement') { - $db->rollback(); + if ($error) + { + $action = 'create'; + } + // Le reste propre a cette action s'affiche en bas de page. + } + + /* + * Action confirm_paiement + */ + if ($action == 'confirm_paiement' && $confirm == 'yes') + { + $error=0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + + $db->begin(); + + // Clean parameters amount if payment is for a credit note + if (GETPOST('type') == 2) + { + foreach ($amounts as $key => $value) // How payment is dispatch + { + $newvalue = price2num($value,'MT'); + $amounts[$key] = -$newvalue; + } + } + + if (! empty($conf->banque->enabled)) + { + // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } + + // Creation of payment line + $paiement = new Paiement($db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array with all payments dispatching + $paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement'); + $paiement->num_paiement = $_POST['num_paiement']; + $paiement->note = $_POST['comment']; + + if (! $error) + { + $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0)); + if ($paiement_id < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } + + if (! $error) + { + $label='(CustomerInvoicePayment)'; + if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)'; + $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank')); + if ($result < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } + + if (! $error) + { + $db->commit(); + + // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card + $invoiceid=0; + foreach ($paiement->amounts as $key => $amount) + { + $facid = $key; + if (is_numeric($amount) && $amount <> 0) + { + if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment + else $invoiceid=$facid; + } + } + if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid; + else $loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id; + header('Location: '.$loc); + exit; + } + else + { + $db->rollback(); + } } } - /* * View */ diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php index c11c1d549a9..7dd671d109f 100644 --- a/htdocs/expedition/fiche.php +++ b/htdocs/expedition/fiche.php @@ -89,473 +89,475 @@ $hookmanager->initHooks(array('expeditioncard')); $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -if ($action == 'add') -{ - $error=0; +if (empty($reshook)) { - $db->begin(); - - $object->note = GETPOST('note','alpha'); - $object->origin = $origin; - $object->origin_id = $origin_id; - $object->weight = GETPOST('weight','int')==''?"NULL":GETPOST('weight','int'); - $object->sizeH = GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int'); - $object->sizeW = GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int'); - $object->sizeS = GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int'); - $object->size_units = GETPOST('size_units','int'); - $object->weight_units = GETPOST('weight_units','int'); - - $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); - - // On va boucler sur chaque ligne du document d'origine pour completer objet expedition - // avec info diverses + qte a livrer - $classname = ucfirst($object->origin); - $objectsrc = new $classname($db); - $objectsrc->fetch($object->origin_id); - - $object->socid = $objectsrc->socid; - $object->ref_customer = $objectsrc->ref_client; - $object->date_delivery = $date_delivery; // Date delivery planed - $object->fk_delivery_address = $objectsrc->fk_delivery_address; - $object->shipping_method_id = GETPOST('shipping_method_id','int'); - $object->tracking_number = GETPOST('tracking_number','alpha'); - $object->ref_int = GETPOST('ref_int','alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); - - $num=count($objectsrc->lines); - $totalqty=0; - for ($i = 0; $i < $num; $i++) + if ($action == 'add') { - $qty = "qtyl".$i; - $j=0; - $sub_qty=array(); - $subtotalqty=0; - $idl="idl".$i; - $batch="batchl".$i."_0"; - if (isset($_POST[$batch])) { - //shipment line with batch-enable product - $qty .= '_'.$j; - while (isset($_POST[$batch])) { - $sub_qty[$j]['q']=GETPOST($qty,'int'); - $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); - $subtotalqty+=$sub_qty[$j]['q']; - $j++; - $batch="batchl".$i."_".$j; - $qty = "qtyl".$i.'_'.$j; + $error=0; - } - $batch_line[$i]['detail']=$sub_qty; - $batch_line[$i]['qty']=$subtotalqty; - $batch_line[$i]['ix_l']=GETPOST($idl,'int'); - $totalqty+=$subtotalqty; - } else { - //Standard product - if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); - } - } + $db->begin(); - if ($totalqty > 0) - { - //var_dump($_POST);exit; + $object->note = GETPOST('note','alpha'); + $object->origin = $origin; + $object->origin_id = $origin_id; + $object->weight = GETPOST('weight','int')==''?"NULL":GETPOST('weight','int'); + $object->sizeH = GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int'); + $object->sizeW = GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int'); + $object->sizeS = GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int'); + $object->size_units = GETPOST('size_units','int'); + $object->weight_units = GETPOST('weight_units','int'); + + $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); + + // On va boucler sur chaque ligne du document d'origine pour completer objet expedition + // avec info diverses + qte a livrer + $classname = ucfirst($object->origin); + $objectsrc = new $classname($db); + $objectsrc->fetch($object->origin_id); + + $object->socid = $objectsrc->socid; + $object->ref_customer = $objectsrc->ref_client; + $object->date_delivery = $date_delivery; // Date delivery planed + $object->fk_delivery_address = $objectsrc->fk_delivery_address; + $object->shipping_method_id = GETPOST('shipping_method_id','int'); + $object->tracking_number = GETPOST('tracking_number','alpha'); + $object->ref_int = GETPOST('ref_int','alpha'); + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + + $num=count($objectsrc->lines); + $totalqty=0; for ($i = 0; $i < $num; $i++) { $qty = "qtyl".$i; - if (! isset($batch_line[$i])) { - if (GETPOST($qty,'int') > 0) - { - $ent = "entl".$i; - $idl = "idl".$i; - $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int'); - if ($entrepot_id < 0) $entrepot_id=''; + $j=0; + $sub_qty=array(); + $subtotalqty=0; + $idl="idl".$i; + $batch="batchl".$i."_0"; + if (isset($_POST[$batch])) { + //shipment line with batch-enable product + $qty .= '_'.$j; + while (isset($_POST[$batch])) { + $sub_qty[$j]['q']=GETPOST($qty,'int'); + $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); + $subtotalqty+=$sub_qty[$j]['q']; + $j++; + $batch="batchl".$i."_".$j; + $qty = "qtyl".$i.'_'.$j; - $ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int')); - if ($ret < 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } else { - if ($batch_line[$i]['qty']>0) { - $ret=$object->addline_batch($batch_line[$i]); - if ($ret < 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } + } + $batch_line[$i]['detail']=$sub_qty; + $batch_line[$i]['qty']=$subtotalqty; + $batch_line[$i]['ix_l']=GETPOST($idl,'int'); + $totalqty+=$subtotalqty; + } else { + //Standard product + if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); + } + } + + if ($totalqty > 0) + { + //var_dump($_POST);exit; + for ($i = 0; $i < $num; $i++) + { + $qty = "qtyl".$i; + if (! isset($batch_line[$i])) { + if (GETPOST($qty,'int') > 0) + { + $ent = "entl".$i; + $idl = "idl".$i; + $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int'); + if ($entrepot_id < 0) $entrepot_id=''; + + $ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int')); + if ($ret < 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } else { + if ($batch_line[$i]['qty']>0) { + $ret=$object->addline_batch($batch_line[$i]); + if ($ret < 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } + } + + if (! $error) + { + $ret=$object->create($user); + if ($ret <= 0) + { + $mesg='
'.$object->error.'
'; + $error++; + } + } + } + else + { + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'
'; + $error++; } if (! $error) { - $ret=$object->create($user); - if ($ret <= 0) - { - $mesg='
'.$object->error.'
'; - $error++; - } - } - } - else - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'
'; - $error++; - } - - if (! $error) - { - $db->commit(); - header("Location: fiche.php?id=".$object->id); - exit; - } - else - { - $db->rollback(); - $_GET["commande_id"]=GETPOST('commande_id','int'); - $action='create'; - } -} - -/* - * Build a receiving receipt - */ -else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) -{ - $result = $object->create_delivery($user); - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT.'/livraison/fiche.php?id='.$result); - exit; - } - else - { - $mesg=$object->error; - } -} - -else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider) -{ - $object->fetch_thirdparty(); - - $result = $object->valid($user); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $ret=$object->fetch($id); // Reload to get new records - $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs); - } - if ($result < 0) - { - dol_print_error($db,$result); - exit; - } -} - -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) -{ - $result = $object->delete(); - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); - exit; - } - else - { - $langs->load("errors"); - setEventMessage($langs->trans($object->error),'errors'); - } -} - -else if ($action == 'reopen' && $user->rights->expedition->valider) -{ - $result = $object->setStatut(0); - if ($result < 0) - { - $mesg = $object->error; - } -} - -else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) -{ - //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); - - $object->fetch($id); - $result=$object->set_date_livraison($user,$datedelivery); - if ($result < 0) - { - $mesg='
'.$object->error.'
'; - } -} - -// Action update description of emailing -else if ($action == 'settrackingnumber' || $action == 'settrackingurl' -|| $action == 'settrueWeight' -|| $action == 'settrueWidth' -|| $action == 'settrueHeight' -|| $action == 'settrueDepth' -|| $action == 'setshipping_method_id') -{ - $error=0; - - if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); - if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); - if ($action == 'settrueWeight') { - $object->trueWeight = trim(GETPOST('trueWeight','int')); - $object->weight_units = GETPOST('weight_units','int'); - } - if ($action == 'settrueWidth') $object->trueWidth = trim(GETPOST('trueWidth','int')); - if ($action == 'settrueHeight'){ - $object->trueHeight = trim(GETPOST('trueHeight','int')); - $object->size_units = GETPOST('size_units','int'); - } - if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); - if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); - - if (! $error) - { - if ($object->update($user) >= 0) - { + $db->commit(); header("Location: fiche.php?id=".$object->id); exit; } - setEventMessage($object->error,'errors'); + else + { + $db->rollback(); + $_GET["commande_id"]=GETPOST('commande_id','int'); + $action='create'; + } } - $action=""; -} - -// Build document -else if ($action == 'builddoc') // En get ou en post -{ - - // Save last template used to generate document - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang; - if (! empty($newlang)) + /* + * Build a receiving receipt + */ + else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); + $result = $object->create_delivery($user); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/livraison/fiche.php?id='.$result); + exit; + } + else + { + $mesg=$object->error; + } } - $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs); - if ($result <= 0) + + else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider) { - dol_print_error($db,$result); - exit; + $object->fetch_thirdparty(); + + $result = $object->valid($user); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $ret=$object->fetch($id); // Reload to get new records + $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs); + } + if ($result < 0) + { + dol_print_error($db,$result); + exit; + } } -} -// Delete file in doc form -elseif ($action == 'remove_file') -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $upload_dir = $conf->expedition->dir_output . "/sending"; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); -} - -/* - * Add file in email form -*/ -if (GETPOST('addfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - dol_add_file_process($upload_dir_tmp,0,0); - $action ='presend'; -} - -/* - * Remove file in email form -*/ -if (GETPOST('removedfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - // TODO Delete only files that was uploaded from email form - dol_remove_file_process(GETPOST('removedfile','int'),0); - $action ='presend'; -} - -/* - * Send mail -*/ -if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha')) -{ - $langs->load('mails'); - -// $ref = dol_sanitizeFileName($object->ref); -// $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf'; - -// if (is_readable($file)) -// { - if (GETPOST('sendto','alpha')) - { - // Le destinataire a ete fourni via le champ libre - $sendto = GETPOST('sendto','alpha'); - $sendtoid = 0; - } - elseif (GETPOST('receiver','alpha') != '-1') - { - // Recipient was provided from combo list - if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } - else // Id du contact - { - $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email'); - $sendtoid = GETPOST('receiver','alpha'); - } - } - - if (dol_strlen($sendto)) - { - $langs->load("commercial"); - - $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>'; - $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>'; - $message = GETPOST('message'); - $sendtocc = GETPOST('sendtocc','alpha'); - $deliveryreceipt = GETPOST('deliveryreceipt','alpha'); - - if ($action == 'send') - { - if (dol_strlen(GETPOST('subject','alpha'))) $subject=GETPOST('subject','alpha'); - else $subject = $langs->transnoentities('Shipping').' '.$object->ref; - $actiontypecode='AC_SHIP'; - $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) - { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - // Send mail - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - $mesg='
'.$mailfile->error.'
'; - } - else - { - $result=$mailfile->sendfile(); - if ($result) - { - $error=0; - - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('SHIPPING_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { - $error++; $object->errors=$interface->errors; - } - // Fin appel triggers - - if ($error) - { - dol_print_error($db); - } - else - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - } - else - { - $langs->load("other"); - $mesg='
'; - if ($mailfile->error) - { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; - } - else - { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - $mesg.='
'; - } - } - } - else - { - $langs->load("other"); - $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; - $action='presend'; - dol_syslog('Recipient email is empty'); - } -/* } + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) + { + $result = $object->delete(); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); + exit; + } else { $langs->load("errors"); - $mesg='
'.$langs->trans('ErrorCantReadFile',$file).'
'; - dol_syslog('Failed to read file: '.$file); - }*/ -} + setEventMessage($langs->trans($object->error),'errors'); + } + } -else if ($action == 'classifybilled') -{ - $object->fetch($id); - $object->set_billed(); -} + else if ($action == 'reopen' && $user->rights->expedition->valider) + { + $result = $object->setStatut(0); + if ($result < 0) + { + $mesg = $object->error; + } + } + else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) + { + //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); + + $object->fetch($id); + $result=$object->set_date_livraison($user,$datedelivery); + if ($result < 0) + { + $mesg='
'.$object->error.'
'; + } + } + + // Action update description of emailing + else if ($action == 'settrackingnumber' || $action == 'settrackingurl' + || $action == 'settrueWeight' + || $action == 'settrueWidth' + || $action == 'settrueHeight' + || $action == 'settrueDepth' + || $action == 'setshipping_method_id') + { + $error=0; + + if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); + if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); + if ($action == 'settrueWeight') { + $object->trueWeight = trim(GETPOST('trueWeight','int')); + $object->weight_units = GETPOST('weight_units','int'); + } + if ($action == 'settrueWidth') $object->trueWidth = trim(GETPOST('trueWidth','int')); + if ($action == 'settrueHeight'){ + $object->trueHeight = trim(GETPOST('trueHeight','int')); + $object->size_units = GETPOST('size_units','int'); + } + if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); + if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); + + if (! $error) + { + if ($object->update($user) >= 0) + { + header("Location: fiche.php?id=".$object->id); + exit; + } + setEventMessage($object->error,'errors'); + } + + $action=""; + } + + // Build document + else if ($action == 'builddoc') // En get ou en post + { + + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + } + + // Delete file in doc form + elseif ($action == 'remove_file') + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $upload_dir = $conf->expedition->dir_output . "/sending"; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + } + + /* + * Add file in email form + */ + if (GETPOST('addfile','alpha')) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory TODO Use a dedicated directory for temp mails files + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + dol_add_file_process($upload_dir_tmp,0,0); + $action ='presend'; + } + + /* + * Remove file in email form + */ + if (GETPOST('removedfile','alpha')) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + // TODO Delete only files that was uploaded from email form + dol_remove_file_process(GETPOST('removedfile','int'),0); + $action ='presend'; + } + + /* + * Send mail + */ + if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha')) + { + $langs->load('mails'); + + // $ref = dol_sanitizeFileName($object->ref); + // $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf'; + + // if (is_readable($file)) + // { + if (GETPOST('sendto','alpha')) + { + // Le destinataire a ete fourni via le champ libre + $sendto = GETPOST('sendto','alpha'); + $sendtoid = 0; + } + elseif (GETPOST('receiver','alpha') != '-1') + { + // Recipient was provided from combo list + if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } + else // Id du contact + { + $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email'); + $sendtoid = GETPOST('receiver','alpha'); + } + } + + if (dol_strlen($sendto)) + { + $langs->load("commercial"); + + $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>'; + $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>'; + $message = GETPOST('message'); + $sendtocc = GETPOST('sendtocc','alpha'); + $deliveryreceipt = GETPOST('deliveryreceipt','alpha'); + + if ($action == 'send') + { + if (dol_strlen(GETPOST('subject','alpha'))) $subject=GETPOST('subject','alpha'); + else $subject = $langs->transnoentities('Shipping').' '.$object->ref; + $actiontypecode='AC_SHIP'; + $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) + { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + // Send mail + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + $mesg='
'.$mailfile->error.'
'; + } + else + { + $result=$mailfile->sendfile(); + if ($result) + { + $error=0; + + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; + $object->actionmsg2 = $actionmsg2; + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('SHIPPING_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { + $error++; $object->errors=$interface->errors; + } + // Fin appel triggers + + if ($error) + { + dol_print_error($db); + } + else + { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); + setEventMessage($mesg); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + } + else + { + $langs->load("other"); + $mesg='
'; + if ($mailfile->error) + { + $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $mesg.='
'.$mailfile->error; + } + else + { + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg.='
'; + } + } + } + else + { + $langs->load("other"); + $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; + $action='presend'; + dol_syslog('Recipient email is empty'); + } + /* } + else + { + $langs->load("errors"); + $mesg='
'.$langs->trans('ErrorCantReadFile',$file).'
'; + dol_syslog('Failed to read file: '.$file); + }*/ + } + + else if ($action == 'classifybilled') + { + $object->fetch($id); + $object->set_billed(); + } +} /* * View diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index bb84e279ba9..b6a4c5a7925 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -68,164 +68,166 @@ $hookmanager->initHooks(array('paymentsupplier')); $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -/* - * Actions - */ -if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) -{ - $error = 0; +if (empty($reshook)) { - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $paiement_id = 0; - $totalpayment = 0; - $atleastonepaymentnotnull = 0; - - // Generate payment array and check if there is payment higher than invoice and payment date before invoice date - $tmpinvoice=new FactureFournisseur($db); - foreach ($_POST as $key => $value) + /* + * Actions + */ + if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes')) { - if (substr($key,0,7) == 'amount_') + $error = 0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $paiement_id = 0; + $totalpayment = 0; + $atleastonepaymentnotnull = 0; + + // Generate payment array and check if there is payment higher than invoice and payment date before invoice date + $tmpinvoice=new FactureFournisseur($db); + foreach ($_POST as $key => $value) { - $cursorfacid = substr($key,7); - $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); - $totalpayment = $totalpayment + $amounts[$cursorfacid]; - if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; - $result=$tmpinvoice->fetch($cursorfacid); - if ($result <= 0) dol_print_error($db); - $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); - if ($amounts[$cursorfacid]) + if (substr($key,0,7) == 'amount_') { - // Check amount - if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) - { - $addwarning=1; - $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier"); - } - // Check date - if ($datepaye && ($datepaye < $tmpinvoice->date)) - { - $langs->load("errors"); - //$error++; - setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); - } + $cursorfacid = substr($key,7); + $amounts[$cursorfacid] = price2num(trim(GETPOST($key))); + $totalpayment = $totalpayment + $amounts[$cursorfacid]; + if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++; + $result=$tmpinvoice->fetch($cursorfacid); + if ($result <= 0) dol_print_error($db); + $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement()); + if ($amounts[$cursorfacid]) + { + // Check amount + if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid]))) + { + $addwarning=1; + $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier"); + } + // Check date + if ($datepaye && ($datepaye < $tmpinvoice->date)) + { + $langs->load("errors"); + //$error++; + setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings'); + } + } + + $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); } - - $formquestion[$i++]=array('type' => 'hidden','name' => $key, 'value' => $_POST[$key]); } - } - // Check parameters - if ($_POST['paiementid'] <= 0) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); - $error++; - } - - if (! empty($conf->banque->enabled)) - { - // If bank module is on, account is required to enter a payment - if (GETPOST('accountid') <= 0) + // Check parameters + if ($_POST['paiementid'] <= 0) { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors'); + $error++; + } + + if (! empty($conf->banque->enabled)) + { + // If bank module is on, account is required to enter a payment + if (GETPOST('accountid') <= 0) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors'); + $error++; + } + } + + if (empty($totalpayment) && empty($atleastonepaymentnotnull)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); + $error++; + } + + if (empty($datepaye)) + { + setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); $error++; } } - if (empty($totalpayment) && empty($atleastonepaymentnotnull)) + /* + * Action add_paiement + */ + if ($action == 'add_paiement') { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors'); - $error++; - } - - if (empty($datepaye)) - { - setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors'); - $error++; - } -} - -/* - * Action add_paiement - */ -if ($action == 'add_paiement') -{ - if ($error) - { - $action = 'create'; - } - // Le reste propre a cette action s'affiche en bas de page. -} - - -/* - * Action confirm_paiement - */ -if ($action == 'confirm_paiement' && $confirm == 'yes') -{ - $error=0; - - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - - if (! $error) - { - $db->begin(); - - // Creation de la ligne paiement - $paiement = new PaiementFourn($db); - $paiement->datepaye = $datepaye; - $paiement->amounts = $amounts; // Array of amounts - $paiement->paiementid = $_POST['paiementid']; - $paiement->num_paiement = $_POST['num_paiement']; - $paiement->note = $_POST['comment']; - if (! $error) + if ($error) { - $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0)); - if ($paiement_id < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } + $action = 'create'; } + // Le reste propre a cette action s'affiche en bas de page. + } + + + /* + * Action confirm_paiement + */ + if ($action == 'confirm_paiement' && $confirm == 'yes') + { + $error=0; + + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); if (! $error) { - $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'',''); - if ($result < 0) - { - setEventMessage($paiement->error, 'errors'); - $error++; - } - } + $db->begin(); - if (! $error) - { - $db->commit(); - - // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card - $invoiceid=0; - foreach ($paiement->amounts as $key => $amount) + // Creation de la ligne paiement + $paiement = new PaiementFourn($db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array of amounts + $paiement->paiementid = $_POST['paiementid']; + $paiement->num_paiement = $_POST['num_paiement']; + $paiement->note = $_POST['comment']; + if (! $error) { - $facid = $key; - if (is_numeric($amount) && $amount <> 0) + $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0)); + if ($paiement_id < 0) { - if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment - else $invoiceid=$facid; + setEventMessage($paiement->error, 'errors'); + $error++; } } - if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/fiche.php?facid='.$invoiceid; - else $loc = DOL_URL_ROOT.'/fourn/paiement/fiche.php?id='.$paiement_id; - header('Location: '.$loc); - exit; - } - else - { - $db->rollback(); + + if (! $error) + { + $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'',''); + if ($result < 0) + { + setEventMessage($paiement->error, 'errors'); + $error++; + } + } + + if (! $error) + { + $db->commit(); + + // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card + $invoiceid=0; + foreach ($paiement->amounts as $key => $amount) + { + $facid = $key; + if (is_numeric($amount) && $amount <> 0) + { + if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment + else $invoiceid=$facid; + } + } + if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/fiche.php?facid='.$invoiceid; + else $loc = DOL_URL_ROOT.'/fourn/paiement/fiche.php?id='.$paiement_id; + header('Location: '.$loc); + exit; + } + else + { + $db->rollback(); + } } } } - /* * View */ diff --git a/htdocs/fourn/fiche.php b/htdocs/fourn/fiche.php index b4ceb2ae1b0..c98b855cdf9 100644 --- a/htdocs/fourn/fiche.php +++ b/htdocs/fourn/fiche.php @@ -54,40 +54,41 @@ $hookmanager->initHooks(array('suppliercard')); $parameters = array('id' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -/* - * Action - */ +if (empty($reshook)) { + /* + * Action + */ -if ($action == 'setsupplieraccountancycode') -{ - $cancelbutton = GETPOST('cancel'); + if ($action == 'setsupplieraccountancycode') + { + $cancelbutton = GETPOST('cancel'); - if (!$cancelbutton) { + if (!$cancelbutton) { - $result = $object->fetch($id); - $object->code_compta_fournisseur = $_POST["supplieraccountancycode"]; - $result = $object->update($object->id, $user, 1, 0, 1); - if ($result < 0) { - $mesg = join(',', $object->errors); + $result = $object->fetch($id); + $object->code_compta_fournisseur = $_POST["supplieraccountancycode"]; + $result = $object->update($object->id, $user, 1, 0, 1); + if ($result < 0) { + $mesg = join(',', $object->errors); + } + $action = ""; } - $action = ""; + } + // conditions de reglement + if ($action == 'setconditions' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + // mode de reglement + if ($action == 'setmode' && $user->rights->societe->creer) + { + $object->fetch($id); + $result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int')); + if ($result < 0) dol_print_error($db,$object->error); } } -// conditions de reglement -if ($action == 'setconditions' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} -// mode de reglement -if ($action == 'setmode' && $user->rights->societe->creer) -{ - $object->fetch($id); - $result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int')); - if ($result < 0) dol_print_error($db,$object->error); -} - /* * View diff --git a/htdocs/product/document.php b/htdocs/product/document.php index 1e8c7b7cd9a..24c8122a3a0 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -76,13 +76,13 @@ $modulepart='produit'; $parameters=array('id'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if (empty($reshook)) { + /* + * Action envoie fichier + */ -/* - * Action envoie fichier - */ - -include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; - + include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php'; +} /* * View diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 527615cc7c4..c5ebe50049a 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -83,125 +83,125 @@ $parameters=array('socid'=>$socid, 'id_prod'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks $error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); -if ($action == 'remove_pf') -{ - $product = new ProductFournisseur($db); - if ($product->fetch($id) > 0) +if (empty($reshook)) { + if ($action == 'remove_pf') { - if ($rowid) + $product = new ProductFournisseur($db); + if ($product->fetch($id) > 0) { - $result=$product->remove_product_fournisseur_price($rowid); - $action = ''; - $mesg = '
'.$langs->trans("PriceRemoved").'.
'; + if ($rowid) + { + $result=$product->remove_product_fournisseur_price($rowid); + $action = ''; + $mesg = '
'.$langs->trans("PriceRemoved").'.
'; + } } } -} -if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel")) -{ - $id_fourn=GETPOST("id_fourn"); - if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn"); - $ref_fourn=GETPOST("ref_fourn"); - if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn"); - $quantity=GETPOST("qty"); - $remise_percent=price2num(GETPOST('remise_percent','alpha')); - $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ; - $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha')); - $tva_tx = price2num($tva_tx); + if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel")) + { + $id_fourn=GETPOST("id_fourn"); + if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn"); + $ref_fourn=GETPOST("ref_fourn"); + if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn"); + $quantity=GETPOST("qty"); + $remise_percent=price2num(GETPOST('remise_percent','alpha')); + $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ; + $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha')); + $tva_tx = price2num($tva_tx); - if ($tva_tx == '') - { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")).'
'; - } - if (empty($quantity)) - { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")).'
'; - } - if (empty($ref_fourn)) - { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")).'
'; - } - if ($id_fourn <= 0) - { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")).'
'; - } - if ($_POST["price"] < 0 || $_POST["price"] == '') - { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")).'
'; - } - - $product = new ProductFournisseur($db); - $result=$product->fetch($id); - if ($result <= 0) - { - $error++; - $mesg=$product->error; - } - - if (! $error) - { - $db->begin(); - - if (! $error) + if ($tva_tx == '') + { + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")).'
'; + } + if (empty($quantity)) { - $ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity); // This insert record with no value for price. Values are update later with update_buyprice - if ($ret == -3) - { - $error++; + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")).'
'; + } + if (empty($ref_fourn)) + { + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")).'
'; + } + if ($id_fourn <= 0) + { + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")).'
'; + } + if ($_POST["price"] < 0 || $_POST["price"] == '') + { + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")).'
'; + } - $product->fetch($product->product_id_already_linked); - $productLink = $product->getNomUrl(1,'supplier'); - - $mesg='
'.$langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink).'
'; - } - else if ($ret < 0) - { - $error++; - $mesg='
'.$product->error.'
'; - } + $product = new ProductFournisseur($db); + $result=$product->fetch($id); + if ($result <= 0) + { + $error++; + $mesg=$product->error; } if (! $error) - { - $supplier=new Fournisseur($db); - $result=$supplier->fetch($id_fourn); - if (isset($_POST['ref_fourn_price_id'])) - $product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']); + { + $db->begin(); - $ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr); - if ($ret < 0) + if (! $error) { - $error++; - $mesg='
'.$product->error.'
'; + $ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity); // This insert record with no value for price. Values are update later with update_buyprice + if ($ret == -3) + { + $error++; + + $product->fetch($product->product_id_already_linked); + $productLink = $product->getNomUrl(1,'supplier'); + + $mesg='
'.$langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink).'
'; + } + else if ($ret < 0) + { + $error++; + $mesg='
'.$product->error.'
'; + } } - } - if (! $error) - { - $db->commit(); - $action=''; - } - else - { - $db->rollback(); - } - } + if (! $error) + { + $supplier=new Fournisseur($db); + $result=$supplier->fetch($id_fourn); + if (isset($_POST['ref_fourn_price_id'])) + $product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']); + + $ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr); + if ($ret < 0) + { + $error++; + $mesg='
'.$product->error.'
'; + } + } + + if (! $error) + { + $db->commit(); + $action=''; + } + else + { + $db->rollback(); + } + } + } + + if (GETPOST('cancel') == $langs->trans("Cancel")) + { + $action = ''; + header("Location: fournisseurs.php?id=".$_GET["id"]); + exit; + } } -if (GETPOST('cancel') == $langs->trans("Cancel")) -{ - $action = ''; - header("Location: fournisseurs.php?id=".$_GET["id"]); - exit; -} - - - /* * view */ diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 38562557e3a..0dbf21ce881 100755 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -61,58 +61,59 @@ $hookmanager->initHooks(array('resource_card')); $parameters=array('resource_id'=>$id); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if (empty($reshook)) { -/******************************************************************* -* ACTIONS -* -* Put here all code to do according to value of "action" parameter -********************************************************************/ + /******************************************************************* + * ACTIONS + * + * Put here all code to do according to value of "action" parameter + ********************************************************************/ -if ($action == 'update' && ! $_POST["cancel"] && $user->rights->resource->write ) -{ - $error=0; - - if (empty($ref)) + if ($action == 'update' && ! $_POST["cancel"] && $user->rights->resource->write ) { - $error++; - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")).'
'; - } + $error=0; - if (! $error) - { - $res = $object->fetch($id); - if ( $res > 0 ) + if (empty($ref)) { - $object->ref = $ref; - $object->description = $description; - $object->fk_code_type_resource = $fk_code_type_resource; - - $result=$object->update($user); - if ($result > 0) + $error++; + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")).'
'; + } + + if (! $error) + { + $res = $object->fetch($id); + if ( $res > 0 ) { - Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; + $object->ref = $ref; + $object->description = $description; + $object->fk_code_type_resource = $fk_code_type_resource; + + $result=$object->update($user); + if ($result > 0) + { + Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessage('
'.$object->error.'
'); + $action='edit'; + } + } else { - setEventMessage('
'.$object->error.'
'); + setEventMessage($object->error,'errors'); $action='edit'; } - } - else + else { - setEventMessage($object->error,'errors'); $action='edit'; } } - else - { - $action='edit'; - } } - /*************************************************** * VIEW * From dacec491ff56cc21c784deb11c54d46359c38131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 19:37:49 +0100 Subject: [PATCH 43/61] Fix: [ bug #1783 ] SQL error when enabling 3rd party module with PostgreSQL and MySQL strict mode ON --- ChangeLog | 2 +- htdocs/core/class/menubase.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a49b467783..ab27963fd2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules - +- Fix: [ bug #1783 ] SQL error when enabling 3rd party module with PostgreSQL and MySQL strict mode ON ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. - Fix: bug 1588 : relative discount. diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index c04697acd39..2f4049ee460 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -152,7 +152,7 @@ class Menubase $sql.= " '".$this->fk_menu."',"; $sql.= " ".($this->fk_mainmenu?"'".$this->fk_mainmenu."'":"null").","; $sql.= " ".($this->fk_leftmenu?"'".$this->fk_leftmenu."'":"null").","; - $sql.= " '".$this->position."',"; + $sql.= " '".(int) $this->position."',"; $sql.= " '".$this->db->escape($this->url)."',"; $sql.= " '".$this->db->escape($this->target)."',"; $sql.= " '".$this->db->escape($this->titre)."',"; From 003aa5ee4433059b1d68ec7e147996bafd467051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 19:41:31 +0100 Subject: [PATCH 44/61] Fix: [ bug #1717 ] Sorting unpaid invoices by amount received brings due amount --- ChangeLog | 1 + htdocs/compta/facture/impayees.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2a49b467783..83a107cb6e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules +- Fix: [ bug #1717 ] Sorting unpaid invoices by amount received brings due amount ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php index d009216bc86..467d2b0636a 100644 --- a/htdocs/compta/facture/impayees.php +++ b/htdocs/compta/facture/impayees.php @@ -535,7 +535,7 @@ if ($resql) print_liste_field_titre($langs->trans("Taxes"),$_SERVER["PHP_SELF"],"f.tva","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Received"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"fk_statut,paye,am","",$param,'align="right"',$sortfield,$sortorder); if (empty($mode)) { From 78905c6af1bd95dd957c4426bb341074b88ff77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 17 Jan 2015 20:29:51 +0100 Subject: [PATCH 45/61] =?UTF-8?q?Fix:=20[=20bug=20#1784=20]=20=C2=AB=20Mes?= =?UTF-8?q?sage=20page=20de=20connexion=20=C2=BB=20n'appara=C3=AEt=20pas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 1 + htdocs/core/tpl/login.tpl.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2a49b467783..a6231b139ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules +- Fix: [ bug #1784 ] « Message page de connexion » n'apparaît pas ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 82748a69b05..f508a595d23 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -203,7 +203,7 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file -
+
Date: Sun, 18 Jan 2015 00:57:03 +0100 Subject: [PATCH 46/61] Update facture.class.php --- htdocs/compta/facture/class/facture.class.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 3388bbdbfe7..683c2c419f0 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2335,8 +2335,11 @@ class Facture extends CommonInvoice } /** + * Update invoice line with percentage + * * @param FactureLigne $line Invoice line * @param int $percent + * @return void */ function update_percent($line, $percent) { @@ -3451,6 +3454,7 @@ class Facture extends CommonInvoice /** * Checks if the invoice is the first of a cycle * + * @return boolean */ function is_first() { @@ -3460,6 +3464,7 @@ class Facture extends CommonInvoice /** * Returns an array containing the previous situations as Facture objects * + * @return mixed -1 if error, array of previous situations */ function get_prev_sits() { @@ -3514,7 +3519,6 @@ class Facture extends CommonInvoice * @return int 0 or 1 if OK, -1 if error * */ - function is_last_in_cycle() { $sql = 'SELECT max(situation_counter) FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_cycle_ref = ' . $this->situation_cycle_ref; @@ -4096,7 +4100,6 @@ class FactureLigne extends CommonInvoiceLine * * @return int >= 0 */ - function get_prev_progress() { if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id == "") { From 6237f68e74e0689ad4d19fa9ae9ca47a1463b46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 18 Jan 2015 01:07:32 +0100 Subject: [PATCH 47/61] Update facture.class.php --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 683c2c419f0..a6cf04715f2 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2338,7 +2338,7 @@ class Facture extends CommonInvoice * Update invoice line with percentage * * @param FactureLigne $line Invoice line - * @param int $percent + * @param int $percent Percentage * @return void */ function update_percent($line, $percent) From 17b14eed88bfb2cf9073b34f2948cbe9ee8b7016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sun, 18 Jan 2015 02:55:59 +0100 Subject: [PATCH 48/61] Updated bug title --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a6231b139ce..d71dc3e7a01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ English Dolibarr ChangeLog - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid. - Fix: withdrawal create error if in the same month are deleted previus withdrawals. - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules -- Fix: [ bug #1784 ] « Message page de connexion » n'apparaît pas +- Fix: [ bug #1784 ] MOTD doesn't show up in Amarok theme ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. From 71e5cf07c6de693e4e775e912b783f613696ddc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sun, 18 Jan 2015 03:12:19 +0100 Subject: [PATCH 49/61] Fix: [ bug #1735 ] Rights to delete expense notes no longer there - cannot delete expense notes --- htdocs/core/modules/modDeplacement.class.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php index 75d3ab328c8..c536553ac4b 100644 --- a/htdocs/core/modules/modDeplacement.class.php +++ b/htdocs/core/modules/modDeplacement.class.php @@ -95,17 +95,17 @@ class modDeplacement extends DolibarrModules $this->rights[3][3] = 0; $this->rights[3][4] = 'supprimer'; - $this->rights[3][0] = 174; - $this->rights[3][1] = 'Lire toutes les notes de frais'; - $this->rights[3][2] = 'd'; - $this->rights[3][3] = 0; - $this->rights[3][4] = 'readall'; + $this->rights[4][0] = 174; + $this->rights[4][1] = 'Lire toutes les notes de frais'; + $this->rights[4][2] = 'd'; + $this->rights[4][3] = 0; + $this->rights[4][4] = 'readall'; - $this->rights[6][0] = 178; - $this->rights[6][1] = 'Exporter les notes de frais et deplacements'; - $this->rights[6][2] = 'd'; - $this->rights[6][3] = 0; - $this->rights[6][4] = 'export'; + $this->rights[5][0] = 178; + $this->rights[5][1] = 'Exporter les notes de frais et deplacements'; + $this->rights[5][2] = 'd'; + $this->rights[5][3] = 0; + $this->rights[5][4] = 'export'; // Exports $r=0; From 48c6897f758fa93f33c9ab62eb05ae3a738c52b4 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Sun, 18 Jan 2015 03:20:35 +0100 Subject: [PATCH 50/61] Store per entity SMTP configuration --- htdocs/admin/mails.php | 12 ++++++------ htdocs/install/mysql/data/llx_const.sql | 6 +++--- htdocs/install/mysql/migration/3.7.0-3.8.0.sql | 8 ++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index b39760c6907..e3908ad19d7 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -65,12 +65,12 @@ if ($action == 'update' && empty($_POST["cancel"])) { dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS"),'chaine',0,'',$conf->entity); // Send mode parameters - dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTP_PORT"])) dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTP_SERVER"])) dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"),'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTPS_ID"])) dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_SMTPS_PW"])) dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',0); - if (isset($_POST["MAIN_MAIL_EMAIL_TLS"])) dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',0); + dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',$conf->entity); // Content parameters dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM", GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO", GETPOST("MAIN_MAIL_ERRORS_TO"), 'chaine',0,'',$conf->entity); diff --git a/htdocs/install/mysql/data/llx_const.sql b/htdocs/install/mysql/data/llx_const.sql index 0c0a98355c0..3b627f3d99b 100644 --- a/htdocs/install/mysql/data/llx_const.sql +++ b/htdocs/install/mysql/data/llx_const.sql @@ -40,13 +40,13 @@ insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG_FILE','DOL_DATA_ROOT/dolibarr.log','chaine','Directory where to write log file',0,0); insert into llx_const (name, value, type, note, visible, entity) values ('SYSLOG_LEVEL','7','chaine','Level of debug info to show',0,0); -insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_SERVER','','chaine','Host or ip address for SMTP server',0,0); -insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_PORT','','chaine','Port for SMTP server',0,0); - insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_UPLOAD_DOC','2048','chaine','Max size for file upload (0 means no upload allowed)',0,0); -- Hidden but specific to one entity insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MONNAIE','EUR','chaine','Monnaie',0,1); + +insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_SERVER','','chaine','Host or ip address for SMTP server',0,1); +insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_SMTP_PORT','','chaine','Port for SMTP server',0,1); insert into llx_const (name, value, type, note, visible, entity) values ('MAIN_MAIL_EMAIL_FROM','robot@domain.com','chaine','EMail emetteur pour les emails automatiques Dolibarr',0,1); -- diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 02265ff86c8..d3f269d6dbe 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -37,3 +37,11 @@ ALTER TABLE llx_facture ADD situation_counter tinyint UNSIGNED; ALTER TABLE llx_facture ADD situation_final boolean; ALTER TABLE llx_facturedet ADD situation_percent real; ALTER TABLE llx_facturedet ADD fk_prev_id integer; + +-- Convert SMTP config to main entity, so new entities don't get the old values +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SENDMODE"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_PORT"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_SERVER"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_ID"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_PW"; +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_EMAIL_TLS"; \ No newline at end of file From f3a313645263ae33fe3d634de8534ac92907614d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 18 Jan 2015 11:38:45 +0100 Subject: [PATCH 51/61] Update html.form.class.php --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c4b025878c5..aa1f79cfb11 100755 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2666,7 +2666,7 @@ class Form * * @return string HTML select */ - function load_situation_invoices($selected = '', $socid) + function load_situation_invoices($selected = '', $socid = '') { global $langs; From 012c571a6c7efcb82730ec32356c18038c52304a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 11:48:52 +0100 Subject: [PATCH 52/61] Fixed: Backward compatibility --- htdocs/comm/action/class/actioncomm.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index dd7819f7dbb..f8e02de72a7 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -138,6 +138,13 @@ class ActionComm extends CommonObject if ($this->elementtype=='commande') $this->elementtype='order'; if ($this->elementtype=='contrat') $this->elementtype='contract'; + if (! is_array($this->userassigned)) // For backward compatibility + { + $tmpid=$this->userassigned; + $this->userassigned=array(); + $this->userassigned[$tmpid]=array('id'=>$tmpid); + } + $userownerid=$this->userownerid; $userdoneid=$this->userdoneid; From 6a294eb02a43ff65c49fbb4c7558b776c2926ed0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 12:29:55 +0100 Subject: [PATCH 53/61] Fixed: Better fix for backward compatibility --- htdocs/comm/action/class/actioncomm.class.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index dd7819f7dbb..2116b4c2530 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -118,6 +118,13 @@ class ActionComm extends CommonObject $error=0; $now=dol_now(); + // Check parameters + if (empty($this->userownerid)) + { + $this->errors[]='ErrorPropertyUserowneridNotDefined'; + return -1; + } + // Clean parameters $this->label=dol_trunc(trim($this->label),128); $this->location=dol_trunc(trim($this->location),128); @@ -137,12 +144,13 @@ class ActionComm extends CommonObject if ($this->elementtype=='facture') $this->elementtype='invoice'; if ($this->elementtype=='commande') $this->elementtype='order'; if ($this->elementtype=='contrat') $this->elementtype='contract'; - + $userownerid=$this->userownerid; $userdoneid=$this->userdoneid; - // Be sure assigned user array is not empty. - if (count($this->userassigned) == 0) $this->userassigned = array('id'=>$userownerid); + // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...). + if (empty($this->userassigned) || count($this->userassigned) == 0 || ! is_array($this->userassigned)) + $this->userassigned = array($userownerid=>array('id'=>$userownerid)); if (! $this->type_id || ! $this->type_code) { @@ -229,6 +237,12 @@ class ActionComm extends CommonObject { foreach($this->userassigned as $key => $val) { + if (! is_array($val)) // For backward compatibility when val=id + { + $tmpid=$val; + $val=array('id'=>$val); + } + $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql.=" VALUES(".$this->id.", 'user', ".$val['id'].", ".($val['mandatory']?$val['mandatory']:'0').", ".($val['transparency']?$val['transparency']:'0').", ".($val['answer_status']?$val['answer_status']:'0').")"; From d45750d914d82ece73d9fbe7df9f995ffb3462c8 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sun, 18 Jan 2015 13:07:39 +0100 Subject: [PATCH 54/61] Ignore content of directory custom Conflicts: htdocs/custom/.gitignore --- htdocs/custom/.gitignore | 8 ++++---- htdocs/custom/index.html | 0 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 htdocs/custom/index.html diff --git a/htdocs/custom/.gitignore b/htdocs/custom/.gitignore index ed069fdfd81..89ebd12182c 100644 --- a/htdocs/custom/.gitignore +++ b/htdocs/custom/.gitignore @@ -1,4 +1,4 @@ -/a* -/b* -/c* -/d* +/* +!.gitignore +!README.md +!index.html \ No newline at end of file diff --git a/htdocs/custom/index.html b/htdocs/custom/index.html new file mode 100644 index 00000000000..e69de29bb2d From 839f73d5687966e80e6d337c3aab5ce48b051e3a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 14:57:25 +0100 Subject: [PATCH 55/61] Update doc --- build/makepack-howto.txt | 4 +--- scripts/odt2pdf/odt2pdf.sh | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build/makepack-howto.txt b/build/makepack-howto.txt index 40b0e5180bc..9e5004f4ba7 100644 --- a/build/makepack-howto.txt +++ b/build/makepack-howto.txt @@ -11,7 +11,6 @@ beta version of Dolibarr, step by step. - Update version/info in /ChangeLog - Update version number with x.y.z-w in htdocs/filefunc.inc.php - Update version number with x.y.z-w in build/debian/changelog -- Update version number with x.y.z-w in build/exe/doliwamp/doliwamp.iss - Update version number with x.y.z-w in build/rpm/*.spec - Commit all changes. - Add a Tag (x.y.betaz_YYYYMMDD) and push it: git push --tags @@ -30,10 +29,9 @@ This files describe steps made by Dolibarr packaging team to make a complete release of Dolibarr, step by step. - Check all files are commited. -- Update version/info in ChangeLog +- Update version/info in ChangeLog. To generate a changelog, you can do "git log x.y.z..HEAD --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^Fix\|New\|Sec'" - Update version number with x.y.z in htdocs/filefunc.inc.php - Update version number with x.y.z in build/debian/changelog -- Update version number with x.y.z in build/exe/doliwamp/doliwamp.iss - Update version number with x.y.z in build/rpm/*.spec - Commit all changes. diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh index 9d9bf18a8c7..c7c768a1244 100755 --- a/scripts/odt2pdf/odt2pdf.sh +++ b/scripts/odt2pdf/odt2pdf.sh @@ -1,8 +1,12 @@ #!/bin/bash # @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com # @copyright GPL License 2013 - Florian HEnry - florian.henry@open-concept.pro - # +# Convert an ODT into a PDF using "jodconverter" tool. +# Dolibarr variable MAIN_ODT_AS_PDF must be defined to have this script called after ODT generation. +# Dolibarr variable MAIN_DOL_SCRIPTS_ROOT must be defined to path of script directories (otherwise dolibarr will try to guess). + + #if [ -f "$1.odt" ] # then # soffice --invisible --convert-to pdf:writer_pdf_Export --outdir $2 "$1.odt" From 28148f8637a948a635cf79370f2656db31112539 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 20:49:57 +0100 Subject: [PATCH 56/61] Fixed: Bad sql requests --- htdocs/install/mysql/migration/3.7.0-3.8.0.sql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index d5ac52fd4aa..f9e00505f0a 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -47,11 +47,11 @@ ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAUL insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 2131, 213, '5', '0', 'VAT 5%', 1); -- Add situation invoices -ALTER TABLE llx_facture ADD situation_cycle_ref integer; -ALTER TABLE llx_facture ADD situation_counter integer; -ALTER TABLE llx_facture ADD situation_final integer; -ALTER TABLE llx_facturedet ADD situation_percent real; -ALTER TABLE llx_facturedet ADD fk_prev_id integer; +ALTER TABLE llx_facture ADD COLUMN situation_cycle_ref integer; +ALTER TABLE llx_facture ADD COLUMN situation_counter integer; +ALTER TABLE llx_facture ADD COLUMN situation_final integer; +ALTER TABLE llx_facturedet ADD COLUMN situation_percent real; +ALTER TABLE llx_facturedet ADD COLUMN fk_prev_id integer; -- Convert SMTP config to main entity, so new entities don't get the old values UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SENDMODE"; From f96fdc7d0a2838f1dc0ac7aaf592a23b6e5030ec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 21:04:39 +0100 Subject: [PATCH 57/61] Regression solved --- htdocs/compta/facture/class/facture.class.php | 4 +-- htdocs/core/lib/price.lib.php | 4 ++- test/phpunit/PricesTest.php | 30 +++++++++---------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 278d8ca70e4..f28f4bdd348 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2027,7 +2027,7 @@ class Facture extends CommonInvoice * @param int $fk_prev_id Previous situation line id reference * @return int <0 if KO, Id of line if OK */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=0, $fk_prev_id='') + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=100, $fk_prev_id='') { global $mysoc, $conf, $langs; @@ -2336,7 +2336,7 @@ class Facture extends CommonInvoice /** * Update invoice line with percentage - * + * * @param FactureLigne $line Invoice line * @param int $percent Percentage * @return void diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index aa3a1e11a46..aac29ad5256 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -49,7 +49,7 @@ * @param int $type 0/1=Product/service * @param Societe $seller Thirdparty seller (we need $seller->country_id property). Provided only if seller is the supplier, otherwise $seller will be $mysoc. * @param array $localtaxes_array Array with localtaxes info (loaded by getLocalTaxesFromRate function). - * @param float $progress Situation invoices progress + * @param float $progress Situation invoices progress (value from 0 to 100, 100 by default) * @return result[ 0=total_ht, * 1=total_vat, * 2=total_ttc, @@ -97,6 +97,8 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt if ($uselocaltax1_rate < 0) $uselocaltax1_rate=$seller->localtax1_assuj; if ($uselocaltax2_rate < 0) $uselocaltax2_rate=$seller->localtax2_assuj; + dol_syslog('Price.lib::calcul_price_total qty='.$qty.' pu='.$pu.' remise_percent_ligne='.$remise_percent_ligne.' txtva='.$txtva.' uselocaltax1_rate='.$uselocaltax1_rate.' uselocaltax2_rate='.$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$ice_base_type.' type='.$type.' progress='.$progress); + // Now we search localtaxes information ourself (rates and types). $localtax1_type=0; $localtax2_type=0; diff --git a/test/phpunit/PricesTest.php b/test/phpunit/PricesTest.php index c01a3701177..9b46f8cc1d6 100755 --- a/test/phpunit/PricesTest.php +++ b/test/phpunit/PricesTest.php @@ -1,20 +1,20 @@ * -* 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. -* + * 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 test/phpunit/PricesTest.php @@ -215,9 +215,9 @@ class PricesTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->fetch($invoiceid); - $this->assertEquals(2.48,$newlocalobject->total_ht); - $this->assertEquals(0.24,$newlocalobject->total_tva); - $this->assertEquals(2.72,$newlocalobject->total_ttc); + $this->assertEquals(2.48,$newlocalobject->total_ht, "testUpdatePrice test1"); + $this->assertEquals(0.24,$newlocalobject->total_tva, "testUpdatePrice test2"); + $this->assertEquals(2.72,$newlocalobject->total_ttc, "testUpdatePrice test3"); // Two lines of 1.24 give 2.48 HT and 2.73 TTC with global vat rounding mode @@ -231,7 +231,7 @@ class PricesTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->fetch($invoiceid); - $this->assertEquals(2.48,$newlocalobject->total_ht); + $this->assertEquals(2.48,$newlocalobject->total_ht, "testUpdatePrice test4"); //$this->assertEquals(0.25,$newlocalobject->total_tva); //$this->assertEquals(2.73,$newlocalobject->total_ttc); } From 47baf232d4b94b3d793d4a533f7971337dcbe05e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 23:02:53 +0100 Subject: [PATCH 58/61] Fix: A method must not change value of original property. --- htdocs/compta/facture/class/facture.class.php | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index f28f4bdd348..1b9f08414c1 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -202,17 +202,6 @@ class Facture extends CommonInvoice if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; $this->brouillon = 1; - if (empty($this->situation_cycle_ref)) { - $this->situation_cycle_ref = 'null'; - } - - if (empty($this->situation_counter)) { - $this->situation_counter = 'null'; - } - - if (empty($this->situation_final)) { - $this->situation_final = '0'; - } dol_syslog(get_class($this)."::create user=".$user->id); @@ -290,23 +279,23 @@ class Facture extends CommonInvoice $sql.= ", '".$this->type."'"; $sql.= ", '".$socid."'"; $sql.= ", '".$this->db->idate($now)."'"; - $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL'); - $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL'); + $sql.= ", ".($this->remise_absolue>0?$this->remise_absolue:'NULL'); + $sql.= ", ".($this->remise_percent>0?$this->remise_percent:'NULL'); $sql.= ", '".$this->db->idate($this->date)."'"; - $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); - $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); + $sql.= ", ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", ".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); + $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); - $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); - $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); - $sql.= ",".($this->fk_project?$this->fk_project:"null"); - $sql.= ','.$this->cond_reglement_id; - $sql.= ",".$this->mode_reglement_id; + $sql.= ", ".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); + $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null"); + $sql.= ", ".($this->fk_project?$this->fk_project:"null"); + $sql.= ", ".$this->cond_reglement_id; + $sql.= ", ".$this->mode_reglement_id; $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."'"; - $sql.= ", ".$this->situation_cycle_ref; - $sql.= ", ".$this->situation_counter; - $sql.= ", ".$this->situation_final; + $sql.= ", ".$this->situation_cycle_ref?"'".$this->db->escape($this->situation_cycle_ref)."'":"null"; + $sql.= ", ".$this->situation_counter?"'".$this->db->escape($this->situation_counter)."'":"null"; + $sql.= ", ".$this->situation_final?$this->situation_final:0; $sql.=")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); From 35546245379cfdc229e6b9baa298999c90289b25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Jan 2015 23:32:13 +0100 Subject: [PATCH 59/61] Fix: A method must not change value of original property. --- htdocs/compta/facture/class/facture.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 1b9f08414c1..a1fe6ee1c4d 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -293,9 +293,9 @@ class Facture extends CommonInvoice $sql.= ", ".$this->cond_reglement_id; $sql.= ", ".$this->mode_reglement_id; $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."'"; - $sql.= ", ".$this->situation_cycle_ref?"'".$this->db->escape($this->situation_cycle_ref)."'":"null"; - $sql.= ", ".$this->situation_counter?"'".$this->db->escape($this->situation_counter)."'":"null"; - $sql.= ", ".$this->situation_final?$this->situation_final:0; + $sql.= ", ".($this->situation_cycle_ref?"'".$this->db->escape($this->situation_cycle_ref)."'":"null"); + $sql.= ", ".($this->situation_counter?"'".$this->db->escape($this->situation_counter)."'":"null"); + $sql.= ", ".($this->situation_final?$this->situation_final:0); $sql.=")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); From fdaa930507ff78011d990fa8e0f1f94422ac0a26 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 19 Jan 2015 01:58:48 +0100 Subject: [PATCH 60/61] Solve phpunit. Fix database field format --- htdocs/install/mysql/migration/3.7.0-3.8.0.sql | 6 +++--- htdocs/install/mysql/tables/llx_facture.sql | 6 +++--- test/phpunit/FactureTest.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index f9e00505f0a..13f367c51fa 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -47,9 +47,9 @@ ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAUL insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 2131, 213, '5', '0', 'VAT 5%', 1); -- Add situation invoices -ALTER TABLE llx_facture ADD COLUMN situation_cycle_ref integer; -ALTER TABLE llx_facture ADD COLUMN situation_counter integer; -ALTER TABLE llx_facture ADD COLUMN situation_final integer; +ALTER TABLE llx_facture ADD COLUMN situation_cycle_ref smallint; +ALTER TABLE llx_facture ADD COLUMN situation_counter smallint; +ALTER TABLE llx_facture ADD COLUMN situation_final smallint; ALTER TABLE llx_facturedet ADD COLUMN situation_percent real; ALTER TABLE llx_facturedet ADD COLUMN fk_prev_id integer; diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql index 144cd349dd6..eada5b46c2e 100644 --- a/htdocs/install/mysql/tables/llx_facture.sql +++ b/htdocs/install/mysql/tables/llx_facture.sql @@ -78,8 +78,8 @@ create table llx_facture import_key varchar(14), extraparams varchar(255), -- for stock other parameters with json format - situation_cycle_ref smallint UNSIGNED, -- situation cycle reference - situation_counter tinyint UNSIGNED, -- situation counter - situation_final boolean -- is the situation final ? + situation_cycle_ref smallint, -- situation cycle reference + situation_counter smallint, -- situation counter + situation_final smallint -- is the situation final ? )ENGINE=innodb; diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php index c68014e9606..3248be7104c 100644 --- a/test/phpunit/FactureTest.php +++ b/test/phpunit/FactureTest.php @@ -216,7 +216,7 @@ class FactureTest extends PHPUnit_Framework_TestCase $newlocalobject=new Facture($this->savdb); $newlocalobject->initAsSpecimen(); $this->changeProperties($newlocalobject); - $this->assertEquals($this->objCompare($localobject,$newlocalobject,true,array('newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement','cond_reglement_doc')), array()); // Actual, Expected + $this->assertEquals($this->objCompare($localobject,$newlocalobject,true,array('newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement','cond_reglement_doc','situation_cycle_ref','situation_counter','situation_final')), array()); // Actual, Expected return $localobject; } From 667565f04fd2c19d10eca7263613289b6d06bf12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 19 Jan 2015 02:38:24 +0100 Subject: [PATCH 61/61] Fix missing table in migration script --- htdocs/install/mysql/migration/3.7.0-3.8.0.sql | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 13f367c51fa..cb70f85a32c 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -59,4 +59,14 @@ UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_PORT UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTP_SERVER"; UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_ID"; UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_SMTPS_PW"; -UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_EMAIL_TLS"; \ No newline at end of file +UPDATE llx_const SET entity = 1 WHERE entity = 0 AND name = "MAIN_MAIL_EMAIL_TLS"; + + +create table llx_bank_account_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; +