From e5f4356afc9061db2a56fc35936d901296e8e557 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 12 Jan 2010 18:02:23 +0000 Subject: [PATCH] Add numbering and pdf module in project --- dev/initdata/initdemo.sql | 2 +- htdocs/admin/project.php | 7 +- htdocs/document.php | 13 + htdocs/html.formcompany.class.php | 30 +- .../livraison/pdf/pdf_typhon.modules.php | 37 ++ htdocs/includes/modules/modProjet.class.php | 14 +- .../modules/project/mod_project_universal.php | 139 ++++ .../modules/project/modules_project.php | 253 ++++++++ .../project/pdf/pdf_baleine.modules.php | 596 ++++++++++++++++++ .../install/mysql/data/llx_c_type_contact.sql | 4 +- .../install/mysql/migration/2.7.0-2.8.0.sql | 2 + htdocs/lib/project.lib.php | 18 +- htdocs/project.class.php | 23 +- htdocs/projet/contact.php | 390 ++++++++++++ 14 files changed, 1483 insertions(+), 45 deletions(-) create mode 100644 htdocs/includes/modules/project/mod_project_universal.php create mode 100644 htdocs/includes/modules/project/modules_project.php create mode 100644 htdocs/includes/modules/project/pdf/pdf_baleine.modules.php create mode 100644 htdocs/projet/contact.php diff --git a/dev/initdata/initdemo.sql b/dev/initdata/initdemo.sql index b08d3d2d8f2..19ab8352eed 100644 --- a/dev/initdata/initdemo.sql +++ b/dev/initdata/initdemo.sql @@ -1182,7 +1182,7 @@ SET character_set_client = @saved_cs_client; LOCK TABLES `llx_c_type_contact` WRITE; /*!40000 ALTER TABLE `llx_c_type_contact` DISABLE KEYS */; -INSERT INTO `llx_c_type_contact` VALUES (10,'contrat','internal','SALESREPSIGN','Commercial signataire du contrat',1),(11,'contrat','internal','SALESREPFOLL','Commercial suivi du contrat',1),(20,'contrat','external','BILLING','Contact client facturation contrat',1),(21,'contrat','external','CUSTOMER','Contact client suivi contrat',1),(22,'contrat','external','SALESREPSIGN','Contact client signataire contrat',1),(31,'propal','internal','SALESREPFOLL','Commercial à l\'origine de la propale',1),(40,'propal','external','BILLING','Contact client facturation propale',1),(41,'propal','external','CUSTOMER','Contact client suivi propale',1),(50,'facture','internal','SALESREPFOLL','Responsable suivi du paiement',1),(60,'facture','external','BILLING','Contact client facturation',1),(61,'facture','external','SHIPPING','Contact client livraison',1),(62,'facture','external','SERVICE','Contact client prestation',1),(80,'projet','internal','PROJECTLEADER','Chef de Projet',1),(81,'projet','external','PROJECTLEADER','Chef de Projet',1),(91,'commande','internal','SALESREPFOLL','Responsable suivi de la commande',1),(100,'commande','external','BILLING','Contact client facturation commande',1),(101,'commande','external','CUSTOMER','Contact client suivi commande',1),(102,'commande','external','SHIPPING','Contact client livraison commande',1),(120,'fichinter','internal','INTERREPFOLL','Responsable suivi de l\'intervention',1),(121,'fichinter','internal','INTERVENING','Intervenant',1),(130,'fichinter','external','BILLING','Contact client facturation intervention',1),(131,'fichinter','external','CUSTOMER','Contact client suivi de l\'intervention',1); +INSERT INTO `llx_c_type_contact` VALUES (10,'contrat','internal','SALESREPSIGN','Commercial signataire du contrat',1),(11,'contrat','internal','SALESREPFOLL','Commercial suivi du contrat',1),(20,'contrat','external','BILLING','Contact client facturation contrat',1),(21,'contrat','external','CUSTOMER','Contact client suivi contrat',1),(22,'contrat','external','SALESREPSIGN','Contact client signataire contrat',1),(31,'propal','internal','SALESREPFOLL','Commercial à l\'origine de la propale',1),(40,'propal','external','BILLING','Contact client facturation propale',1),(41,'propal','external','CUSTOMER','Contact client suivi propale',1),(50,'facture','internal','SALESREPFOLL','Responsable suivi du paiement',1),(60,'facture','external','BILLING','Contact client facturation',1),(61,'facture','external','SHIPPING','Contact client livraison',1),(62,'facture','external','SERVICE','Contact client prestation',1),(80,'project','internal','PROJECTLEADER','Chef de Projet',1),(81,'project','external','PROJECTLEADER','Chef de Projet',1),(91,'commande','internal','SALESREPFOLL','Responsable suivi de la commande',1),(100,'commande','external','BILLING','Contact client facturation commande',1),(101,'commande','external','CUSTOMER','Contact client suivi commande',1),(102,'commande','external','SHIPPING','Contact client livraison commande',1),(120,'fichinter','internal','INTERREPFOLL','Responsable suivi de l\'intervention',1),(121,'fichinter','internal','INTERVENING','Intervenant',1),(130,'fichinter','external','BILLING','Contact client facturation intervention',1),(131,'fichinter','external','CUSTOMER','Contact client suivi de l\'intervention',1); /*!40000 ALTER TABLE `llx_c_type_contact` ENABLE KEYS */; UNLOCK TABLES; diff --git a/htdocs/admin/project.php b/htdocs/admin/project.php index cd5f324c215..256a7e71721 100644 --- a/htdocs/admin/project.php +++ b/htdocs/admin/project.php @@ -26,6 +26,7 @@ require("./pre.inc.php"); require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php"); require_once(DOL_DOCUMENT_ROOT.'/project.class.php'); +require_once(DOL_DOCUMENT_ROOT.'/task.class.php'); $langs->load("admin"); $langs->load("other"); @@ -94,7 +95,7 @@ if ($_GET["action"] == 'del') { $type='project'; $sql = "DELETE FROM ".MAIN_DB_PREFIX."document_model"; - $sql.= " WHERE nom = '".$_GET["value"]; + $sql.= " WHERE nom = '".$_GET["value"]."'"; $sql.= " AND type = '".$type."'"; $sql.= " AND entity = ".$conf->entity; if ($db->query($sql)) @@ -115,7 +116,7 @@ if ($_GET["action"] == 'setdoc') // On active le modele $type='project'; $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."document_model"; - $sql_del.= " WHERE nom = '".$_GET["value"]; + $sql_del.= " WHERE nom = '".$_GET["value"]."'"; $sql_del.= " AND type = '".$type."'"; $sql_del.= " AND entity = ".$conf->entity; $result1=$db->query($sql_del); @@ -177,7 +178,7 @@ if ($handle) while (($file = readdir($handle))!==false) { - if (substr($file, 0, 25) == 'mod_project_' && substr($file, strlen($file)-3, 3) == 'php') + if (substr($file, 0, 12) == 'mod_project_' && substr($file, strlen($file)-3, 3) == 'php') { $file = substr($file, 0, strlen($file)-4); diff --git a/htdocs/document.php b/htdocs/document.php index 12262052f8a..f50584ebb37 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -161,6 +161,7 @@ if ($modulepart) $original_file=$conf->propale->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."propal WHERE ref='$refname'"; } + // Wrapping pour les commandes if ($modulepart == 'commande') { @@ -172,6 +173,18 @@ if ($modulepart) $original_file=$conf->commande->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande WHERE ref='$refname'"; } + + // Wrapping pour les projets + if ($modulepart == 'project') + { + $user->getrights('projet'); + if ($user->rights->projet->lire || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->projet->dir_output.'/'.$original_file; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='$refname'"; + } // Wrapping pour les commandes fournisseurs if ($modulepart == 'commande_fournisseur') diff --git a/htdocs/html.formcompany.class.php b/htdocs/html.formcompany.class.php index c2c572b484d..b394cc2d281 100644 --- a/htdocs/html.formcompany.class.php +++ b/htdocs/html.formcompany.class.php @@ -37,7 +37,7 @@ class FormCompany /** * \brief Constructeur - * \param DB handler d'acc�s base de donn�e + * \param DB handler d'acces base de donnee */ function FormCompany($DB) { @@ -177,13 +177,13 @@ class FormCompany /** - * \brief Retourne la liste d�roulante des d�partements/province/cantons tout pays confondu ou pour un pays donn�. + * \brief Retourne la liste deroulante des departements/province/cantons tout pays confondu ou pour un pays donne. * \remarks Dans le cas d'une liste tout pays confondus, l'affichage fait une rupture sur le pays. - * \remarks La cle de la liste est le code (il peut y avoir plusieurs entr�e pour - * un code donn�e mais dans ce cas, le champ pays diff�re). - * Ainsi les liens avec les d�partements se font sur un d�partement ind�pendemment de son nom. - * \param selected code forme juridique a pr�s�lectionn� - * \param pays_code 0=liste tous pays confondus, sinon code du pays � afficher + * \remarks La cle de la liste est le code (il peut y avoir plusieurs entree pour + * un code donnee mais dans ce cas, le champ pays differe). + * Ainsi les liens avec les departements se font sur un departement independemment de son nom. + * \param selected code forme juridique a preselectionne + * \param pays_code 0=liste tous pays confondus, sinon code du pays a afficher */ function select_departement($selected='',$pays_code=0) { @@ -259,9 +259,9 @@ class FormCompany /** - * \brief Retourne la liste d�roulante des regions actives dont le pays est actif - * \remarks La cle de la liste est le code (il peut y avoir plusieurs entr�e pour - * un code donn�e mais dans ce cas, le champ pays et lang diff�re). + * \brief Retourne la liste deroulante des regions actives dont le pays est actif + * \remarks La cle de la liste est le code (il peut y avoir plusieurs entree pour + * un code donnee mais dans ce cas, le champ pays et lang differe). * Ainsi les liens avec les regions se font sur une region independemment * de son nom. */ @@ -321,8 +321,8 @@ class FormCompany /** - * \brief Retourne la liste d�roulante des civilite actives - * \param selected civilite pr�-s�lectionn�e + * \brief Retourne la liste deroulante des civilite actives + * \param selected civilite pre-selectionnee */ function select_civilite($selected='') { @@ -369,10 +369,10 @@ class FormCompany /** - * \brief Retourne la liste d�roulante des formes juridiques tous pays confondus ou pour un pays donn�. + * \brief Retourne la liste deroulante des formes juridiques tous pays confondus ou pour un pays donne. * \remarks Dans le cas d'une liste tous pays confondu, on affiche une rupture sur le pays - * \param selected Code forme juridique a pr�-s�lectionn� - * \param pays_code 0=liste tous pays confondus, sinon code du pays � afficher + * \param selected Code forme juridique a pre-selectionne + * \param pays_code 0=liste tous pays confondus, sinon code du pays a afficher */ function select_forme_juridique($selected='',$pays_code=0) { diff --git a/htdocs/includes/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/includes/modules/livraison/pdf/pdf_typhon.modules.php index 6aeab1e5cf3..6f4b3ff65f7 100644 --- a/htdocs/includes/modules/livraison/pdf/pdf_typhon.modules.php +++ b/htdocs/includes/modules/livraison/pdf/pdf_typhon.modules.php @@ -358,6 +358,43 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs); $bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1; } + + $requeteTest = "SELECT ref, label, co.qty-li.qty"; + $requeteTest = $requeteTest." FROM llx_commandedet AS co"; + //$requeteTest = $requeteTest." INNER JOIN llx_element_element AS el ON co.fk_commande = el.fk_source"; + $requeteTest = $requeteTest." INNER JOIN llx_livraisondet AS li"; + $requeteTest = $requeteTest." ON li.fk_origin_line = co.rowid"; + $requeteTest = $requeteTest." INNER JOIN llx_product AS pr"; + $requeteTest = $requeteTest." ON pr.rowid = li.fk_product"; + $requeteTest = $requeteTest." WHERE fk_livraison =".$object->id; + + $resultaTest = $this->db->query($requeteTest); + + if ($this->db->num_rows($resultaTest)) { + + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('Arial','',9); + $pdf->SetY(-65); + + $w=array(40,100,50); + $header=array('Reference','Libelle','Quantite'); + + //En-tête + for($i=0;$iCell($w[$i],7,$header[$i],1,0,'C'); + $pdf->Ln(); + + //Données + while($ligneTest = $this->db->fetch_array($resultaTest)) + { + if ($ligneTest[2] > 0) + { + $pdf->Cell($w[0], 6, $ligneTest[0], 1, 0, 'L'); + $pdf->Cell($w[1], 6, $ligneTest[1], 1, 0, 'L'); + $pdf->Cell($w[2], 6, $ligneTest[2], 1, 1, 'R'); + } + } + } /* diff --git a/htdocs/includes/modules/modProjet.class.php b/htdocs/includes/modules/modProjet.class.php index 6254023e7dd..68410e876be 100644 --- a/htdocs/includes/modules/modProjet.class.php +++ b/htdocs/includes/modules/modProjet.class.php @@ -62,7 +62,7 @@ class modProjet extends DolibarrModules $this->picto='project'; // Data directories to create when module is enabled - $this->dirs = array(); + $this->dirs = array("/project/temp"); // Dependancies $this->depends = array(); @@ -70,6 +70,18 @@ class modProjet extends DolibarrModules // Constants $this->const = array(); + + $this->const[0][0] = "PROJECT_ADDON_PDF"; + $this->const[0][1] = "chaine"; + $this->const[0][2] = "baleine"; + $this->const[0][3] = 'Nom du gestionnaire de generation des projets en PDF'; + $this->const[0][4] = 0; + + $this->const[1][0] = "PROJECT_ADDON"; + $this->const[1][1] = "chaine"; + $this->const[1][2] = "mod_project_universal"; + $this->const[1][3] = 'Nom du gestionnaire de numerotation des projets'; + $this->const[1][4] = 0; // Boxes $this->boxes = array(); diff --git a/htdocs/includes/modules/project/mod_project_universal.php b/htdocs/includes/modules/project/mod_project_universal.php new file mode 100644 index 00000000000..6e5e6f7b4b4 --- /dev/null +++ b/htdocs/includes/modules/project/mod_project_universal.php @@ -0,0 +1,139 @@ + + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/includes/modules/project/mod_project_universal.php + * \ingroup project + * \brief Fichier contenant la classe du modele de numerotation de reference de projet Universal + * \version $Id$ + */ + +require_once(DOL_DOCUMENT_ROOT ."/includes/modules/project/modules_project.php"); + + +/** + * \class mod_project_universal + * \brief Classe du modele de numerotation de reference de projet Universal + */ +class mod_project_universal extends ModeleNumRefProjects +{ + var $version='dolibarr'; // 'development', 'experimental', 'dolibarr' + var $error = ''; + var $nom = 'Universal'; + + + /** + * \brief Renvoi la description du modele de numerotation + * \return string Texte descripif + */ + function info() + { + global $conf,$langs; + + $langs->load("projects"); + $langs->load("admin"); + + $form = new Form($db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + $tooltip=$langs->trans("GenericMaskCodes",$langs->transnoentities("Project")); + $tooltip.=$langs->trans("GenericMaskCodes2"); + $tooltip.=$langs->trans("GenericMaskCodes3"); + $tooltip.=$langs->trans("GenericMaskCodes4a",$langs->transnoentities("Project"),$langs->transnoentities("Project")); + $tooltip.=$langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte.= ''; + $texte.= ''; + + $texte.= ''; + + $texte.= ''; + + $texte.= '
'.$langs->trans("Mask").':'.$form->textwithpicto('',$tooltip,1,1).' 
'; + $texte.= '
'; + + return $texte; + } + + /** + * \brief Renvoi un exemple de numerotation + * \return string Example + */ + function getExample() + { + global $conf,$langs,$mysoc; + + $old_code_client=$mysoc->code_client; + $mysoc->code_client='CCCCCCCCCC'; + $numExample = $this->getNextValue($mysoc,''); + $mysoc->code_client=$old_code_client; + + if (! $numExample) + { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * \brief Return next value + * \param objsoc Object third party + * \param commande Object project + * \return string Value if OK, 0 if KO + */ + function getNextValue($objsoc=0,$project='') + { + global $db,$conf; + + require_once(DOL_DOCUMENT_ROOT ."/lib/functions2.lib.php"); + + // On defini critere recherche compteur + $mask=$conf->global->PROJECT_UNIVERSAL_MASK; + + if (! $mask) + { + $this->error='NotConfigured'; + return 0; + } + + $numFinal=get_next_value($db,$mask,'projet','ref','',$objsoc->code_client,$project->datec); + + return $numFinal; + } + + + /** \brief Renvoie la reference de commande suivante non utilisee + * \param objsoc Object third party + * \param commande Object project + * \return string Texte descripif + */ + function project_get_num($objsoc=0,$project='') + { + return $this->getNextValue($objsoc,$project); + } +} + +?> \ No newline at end of file diff --git a/htdocs/includes/modules/project/modules_project.php b/htdocs/includes/modules/project/modules_project.php new file mode 100644 index 00000000000..375350c6734 --- /dev/null +++ b/htdocs/includes/modules/project/modules_project.php @@ -0,0 +1,253 @@ + + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/includes/modules/project/modules_project.php + * \ingroup project + * \brief File that contain parent class for projects models + * and parent class for projects numbering models + * \version $Id$ + */ +require_once(DOL_DOCUMENT_ROOT.'/lib/pdf.lib.php'); +require_once(DOL_DOCUMENT_ROOT.'/includes/fpdf/fpdfi/fpdi_protection.php'); + + +/** + * \class ModelePDFProjects + * \brief Parent class for projects models + */ + +class ModelePDFProjects extends FPDF +{ + var $error=''; + + /** + * \brief Renvoi le dernier message d'erreur de creation de PDF du projet + */ + function pdferror() + { + return $this->error; + } + + /** + * \brief Renvoi la liste des modeles actifs + */ + function liste_modeles($db) + { + global $conf; + + $type='project'; + $liste=array(); + + $sql = "SELECT nom as id, nom as lib"; + $sql.= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql.= " WHERE type = '".$type."'"; + $sql.= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $row = $db->fetch_row($resql); + $liste[$row[0]]=$row[1]; + $i++; + } + } + else + { + $this->error=$db->error(); + return -1; + } + return $liste; + } + +} + + + +/** + * \class ModeleNumRefProjects + * \brief Classe mere des modeles de numerotation des references de projets + */ + +class ModeleNumRefProjects +{ + var $error=''; + + /** + * \brief Return if a module can be used or not + * \return boolean true if module can be used + */ + function isEnabled() + { + return true; + } + + /** + * \brief Renvoi la description par defaut du modele de numerotation + * \return string Texte descripif + */ + function info() + { + global $langs; + $langs->load("projects"); + return $langs->trans("NoDescription"); + } + + /** + * \brief Renvoi un exemple de numerotation + * \return string Example + */ + function getExample() + { + global $langs; + $langs->load("projects"); + return $langs->trans("NoExample"); + } + + /** + * \brief Test si les numeros deja en vigueur dans la base ne provoquent pas de + * de conflits qui empechera cette numerotation de fonctionner. + * \return boolean false si conflit, true si ok + */ + function canBeActivated() + { + return true; + } + + /** + * \brief Renvoi prochaine valeur attribuee + * \return string Valeur + */ + function getNextValue() + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * \brief Renvoi version du module numerotation + * \return string Valeur + */ + function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') return $langs->trans("VersionDevelopment"); + if ($this->version == 'experimental') return $langs->trans("VersionExperimental"); + if ($this->version == 'dolibarr') return DOL_VERSION; + return $langs->trans("NotAvailable"); + } +} + + +/** + * \brief Create object on disk + * \param db objet base de donnee + * \param deliveryid id object + * \param modele force le modele a utiliser ('' to not force) + * \param outputlangs objet lang a utiliser pour traduction + * \return int 0 si KO, 1 si OK + */ +function project_pdf_create($db, $comid, $modele,$outputlangs) +{ + global $langs; + $langs->load("projects"); + + $dir = DOL_DOCUMENT_ROOT."/includes/modules/project/pdf/"; + + // Positionne modele sur le nom du modele de projet a utiliser + if (! strlen($modele)) + { + if (! empty($conf->global->PROJECT_ADDON_PDF)) + { + $modele = $conf->global->PROJECT_ADDON_PDF; + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_PROJECT_ADDON_PDF_NotDefined"); + return 0; + } + } + // Charge le modele + $file = "pdf_".$modele.".modules.php"; + if (file_exists($dir.$file)) + { + $classname = "pdf_".$modele; + require_once($dir.$file); + + $obj = new $classname($db); + + // We save charset_output to restore it because write_file can change it if needed for + // output format that does not support UTF8. + $sav_charset_output=$outputlangs->charset_output; + if ($obj->write_file($comid,$outputlangs) > 0) + { + // on supprime l'image correspondant au preview + project_delete_preview($db, $comid); + + $outputlangs->charset_output=$sav_charset_output; + return 1; + } + else + { + $outputlangs->charset_output=$sav_charset_output; + dol_syslog("Erreur dans project_pdf_create"); + dol_print_error($db,$obj->pdferror()); + return 0; + } + } + else + { + print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file); + return 0; + } +} +function project_delete_preview($db, $projectid) +{ + global $langs,$conf; + + $project = new Project($db,"",$projectid); + $project->fetch($projectid); + $client = new Societe($db); + $client->fetch($project->socid); + + if ($conf->projet->dir_output.'/commande') + { + $projectRef = dol_sanitizeFileName($project->ref); + $dir = $conf->projet->dir_output . "/" . $projectRef ; + $file = $dir . "/" . $projectRef . ".pdf.png"; + + if ( file_exists( $file ) && is_writable( $file ) ) + { + if ( ! dol_delete_file($file) ) + { + $this->error=$langs->trans("ErrorFailedToOpenFile",$file); + return 0; + } + } + } + + return 1; +} +?> diff --git a/htdocs/includes/modules/project/pdf/pdf_baleine.modules.php b/htdocs/includes/modules/project/pdf/pdf_baleine.modules.php new file mode 100644 index 00000000000..73ba5e2db11 --- /dev/null +++ b/htdocs/includes/modules/project/pdf/pdf_baleine.modules.php @@ -0,0 +1,596 @@ + + + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/includes/modules/project/pdf/pdf_baleine.modules.php + * \ingroup project + * \brief Fichier de la classe permettant de generer les projets au modele Baleine + * \author Regis Houssin + * \version $Id$ + */ + +require_once(DOL_DOCUMENT_ROOT."/includes/modules/project/modules_project.php"); +require_once(DOL_DOCUMENT_ROOT."/project.class.php"); +require_once(DOL_DOCUMENT_ROOT."/task.class.php"); +require_once(DOL_DOCUMENT_ROOT."/lib/company.lib.php"); + + +/** + * \class pdf_baleine + * \brief Classe permettant de generer les projets au modele Baleine + */ + +class pdf_baleine extends ModelePDFProjects +{ + var $emetteur; // Objet societe qui emet + + /** + * \brief Constructor + * \param db Database handler + */ + function pdf_baleine($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("projects"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "baleine"; + $this->description = $langs->trans("DocumentModelBaleine"); + + // Dimension page pour format A4 + $this->type = 'pdf'; + $this->page_largeur = 210; + $this->page_hauteur = 297; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=10; + $this->marge_droite=10; + $this->marge_haute=10; + $this->marge_basse=10; + + $this->option_logo = 1; // Affiche logo FAC_PDF_LOGO + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_codeproduitservice = 1; // Affiche code produit-service + + $this->franchise=!$mysoc->tva_assuj; + + // Recupere emmetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'�tait pas d�fini + + // Defini position des colonnes + $this->posxdesc=$this->marge_gauche+1; + $this->posxcomm=120; + $this->posxtva=121; + $this->posxup=132; + $this->posxqty=168; + $this->posxdiscount=162; + $this->postotalht=177; + + $this->tva=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + } + + /** + * \brief Renvoi dernere erreur + * \return string Derniere erreur + */ + function pdferror() + { + return $this->error; + } + + /** + * \brief Fonction generant le projet sur le disque + * \param delivery Object project a generer + * \param outputlangs Lang output object + * \return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs) + { + global $user,$langs,$conf; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // Force output charset to ISO, because, FPDF expect text encoded in ISO + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='ISO-8859-1'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("projects"); + + if ($conf->projet->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Project($this->db); + $object->fetch($id); + + if ($result < 0) + { + dol_print_error($db,$object->error); + } + } + + $nblignes = sizeof($object->lignes); + + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->projet->dir_output; + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + + if (! file_exists($dir)) + { + if (create_exdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Protection et encryption du pdf + if ($conf->global->PDF_SECURITY_ENCRYPTION) + { + $pdf=new FPDI_Protection('P','mm',$this->format); + $pdfrights = array('print'); // Ne permet que l'impression du document + $pdfuserpass = ''; // Mot de passe pour l'utilisateur final + $pdfownerpass = NULL; // Mot de passe du proprietaire, cree aleatoirement si pas defini + $pdf->SetProtection($pdfrights,$pdfuserpass,$pdfownerpass); + } + else + { + $pdf=new FPDI('P','mm',$this->format); + } + + // Complete object by loading several other informations + $task = new Task($this->db); + $result = $task->fetch($object->id); + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("Project")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->fullname)); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Project")); + if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + $pdf->SetAutoPageBreak(1,0); + + // New page + $pdf->AddPage(); + $pagenb++; + $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('Arial','', 9); + $pdf->MultiCell(0, 3, '', 0, 'J'); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $tab_top = 90; + $tab_top_newpage = 50; + $tab_height = 110; + $tab_height_newpage = 150; + + // Affiche notes + if (! empty($object->note_public)) + { + $tab_top = 88; + + $pdf->SetFont('Arial','', 9); // Dans boucle pour gerer multi-page + $pdf->SetXY ($this->posxdesc-1, $tab_top); + $pdf->MultiCell(190, 3, $outputlangs->convToOutputCharset($object->note_public), 0, 'J'); + $nexY = $pdf->GetY(); + $height_note=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY+6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Boucle sur les lignes + for ($i = 0 ; $i < $nblignes ; $i++) + { + $curY = $nexY; + + // Description de la ligne produit + $libelleproduitservice=pdf_getlinedesc($object->lignes[$i],$outputlangs); + + $pdf->SetFont('Arial','', 9); // Dans boucle pour gerer multi-page + + $pdf->writeHTMLCell(108, 3, $this->posxdesc-1, $curY, $outputlangs->convToOutputCharset($libelleproduitservice), 0, 1); + + $pdf->SetFont('Arial','', 9); // On repositionne la police par defaut + $nexY = $pdf->GetY(); + + // Quantity + $pdf->SetXY ($this->posxqty, $curY); + $pdf->MultiCell(30, 3, $object->lignes[$i]->qty_shipped, 0, 'R'); + + $nexY+=2; // Passe espace entre les lignes + + // Cherche nombre de lignes a venir pour savoir si place suffisante + if ($i < ($nblignes - 1)) // If it's not last line + { + //on recupere la description du produit suivant + $follow_descproduitservice = $object->lignes[$i+1]->desc; + //on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres) + $nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4); + } + else // If it's last line + { + $nblineFollowDesc = 0; + } + + // Test if a new page is required + if ($pagenb == 1) + { + $tab_top_in_current_page=$tab_top; + $tab_height_in_current_page=$tab_height; + } + else + { + $tab_top_in_current_page=$tab_top_newpage; + $tab_height_in_current_page=$tab_height_newpage; + } + if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) + { + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs); + } + + $this->_pagefoot($pdf, $object, $outputlangs); + + // New page + $pdf->AddPage(); + $pagenb++; + $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->SetFont('Arial','', 9); + $pdf->MultiCell(0, 3, '', 0, 'J'); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $nexY = $tab_top_newpage + 7; + } + } + + // Show square + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs); + $bottomlasttab=$tab_top + $tab_height + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs); + $bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1; + } + + + /* + * Pied de page + */ + $this->_pagefoot($pdf,$object,$outputlangs); + $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + return 1; // Pas d'erreur + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + $this->error=$langs->transnoentities("ErrorConstantNotDefined","LIVRAISON_OUTPUTDIR"); + return 0; + } + + + /* + * \brief Affiche la grille des lignes + * \param pdf objet PDF + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs) + { + global $conf,$mysoc; + + // Montants exprimes en (en tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('Arial','',8); + //$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->monnaie)); + //$pdf->Text($this->page_largeur - $this->marge_droite - $pdf->GetStringWidth($titre), $tab_top-1, $titre); + + $pdf->SetDrawColor(128,128,128); + + // Rect prend une longueur en 3eme param + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); + // line prend une position y en 3eme param + $pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6); + + $pdf->SetFont('Arial','',10); + + $pdf->SetXY ($this->posxdesc-1, $tab_top+2); + $pdf->MultiCell(80,2, $outputlangs->transnoentities("Designation"),'','L'); + + // Modif SEB pour avoir une col en plus pour les commentaires clients + $pdf->line($this->posxcomm, $tab_top, $this->posxcomm, $tab_top + $tab_height); + $pdf->SetXY ($this->posxcomm, $tab_top+2); + $pdf->MultiCell(80,2, $outputlangs->transnoentities("Comments"),'','L'); + + // Qty + $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxqty-1, $tab_top+2); + $pdf->MultiCell(30, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); + + // Modif Seb cadres signatures + $pdf->SetFont('Arial','',10); + $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; + $pdf->Rect($this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25 ); + $pdf->SetXY ($this->marge_gauche + 2, $tab_top + $tab_height + 5); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->nom).":",'','L'); + + $pdf->Rect(2*$larg_sign+$this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25 ); + $pdf->SetXY (2*$larg_sign+$this->marge_gauche + 2, $tab_top + $tab_height + 5); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); + + } + + /** + * \brief Affiche en-tete bon livraison + * \param pdf objet PDF + * \param delivery object delivery + * \param showadress 0=non, 1=oui + */ + function _pagehead(&$pdf, $object, $showadress=1, $outputlangs) + { + global $langs,$conf,$mysoc; + + pdf_pagehead($pdf,$outputlangs,$pdf->page_hauteur); + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('Arial','B',13); + + $posy=$this->marge_haute; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$mysoc->logo; + if ($mysoc->logo) + { + if (is_readable($logo)) + { + $pdf->Image($logo, $this->marge_gauche, $posy, 0, 24); + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('Arial','B',8); + $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + } + } + else $pdf->MultiCell(100, 4, $this->emetteur->nom, 0, 'L'); + + $pdf->SetFont('Arial','B',13); + $pdf->SetXY(100,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '' , 'R'); + $pdf->SetFont('Arial','',12); + + $posy+=6; + $pdf->SetXY(100,$posy); + $pdf->SetTextColor(0,0,60); + if ($object->date_valid) + { + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date_valid,"%d %b %Y",false,$outputlangs,true), '', 'R'); + } + else + { + $pdf->SetTextColor(255,0,0); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryNotValidated"), '', 'R'); + $pdf->SetTextColor(0,0,60); + } + + $pdf->SetTextColor(0,0,60); + + // Add list of linked orders + $object->load_object_linked(); + + if ($conf->commande->enabled) + { + $outputlangs->load('orders'); + foreach($object->linked_object as $key => $val) + { + if ($val['type'] == 'commande') + { + $newobject=new Commande($this->db); + $result=$newobject->fetch($val['linkid']); + if ($result >= 0) + { + $posy+=4; + $pdf->SetXY(100,$posy); + $pdf->SetFont('Arial','',9); + $text=$newobject->ref; + if ($newobject->ref_client) $text.=' ('.$newobject->ref_client.')'; + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R'); + } + } + } + } + + if ($showadress) + { + // Emetteur + $posy=42; + $hautcadre=40; + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('Arial','',8); + $pdf->SetXY($this->marge_gauche,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":"); + + + $pdf->SetXY($this->marge_gauche,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + + + $pdf->SetXY($this->marge_gauche+2,$posy+3); + + // Nom emetteur + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('Arial','B',11); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->nom), 0, 'L'); + + // Sender properties + $carac_emetteur = ''; + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($this->emetteur->address); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($this->emetteur->cp).' '.$outputlangs->convToOutputCharset($this->emetteur->ville); + $carac_emetteur .= "\n"; + // Tel + if ($this->emetteur->tel) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Phone").": ".$outputlangs->convToOutputCharset($this->emetteur->tel); + // Fax + if ($this->emetteur->fax) $carac_emetteur .= ($carac_emetteur ? ($this->emetteur->tel ? " - " : "\n") : '' ).$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($this->emetteur->fax); + // EMail + if ($this->emetteur->email) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($this->emetteur->email); + // Web + if ($this->emetteur->url) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($this->emetteur->url); + + $pdf->SetFont('Arial','',9); + $pdf->SetXY($this->marge_gauche+2,$posy+9); + $pdf->MultiCell(80, 3, $carac_emetteur); + + // Client destinataire + $posy=42; + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('Arial','',8); + $pdf->SetXY(102,$posy-5); + $pdf->MultiCell(80,5, $outputlangs->transnoentities("DeliveryAddress").":"); + + // Cadre client destinataire + $pdf->rect(100, $posy, 100, $hautcadre); + + $object->fetch_client(); + + // If SHIPPING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->commande->getIdContact('external','SHIPPING'); + if (sizeof($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + if ($usecontact) + { + $socname = $object->client->nom; + $carac_client_name=$outputlangs->convToOutputCharset($socname); + + // Customer name + $carac_client = $outputlangs->convToOutputCharset($object->contact->getFullName($outputlangs,1,1)); + + // Customer properties + $carac_client.="\n".$outputlangs->convToOutputCharset($object->contact->address); + $carac_client.="\n".$outputlangs->convToOutputCharset($object->contact->cp) . " " . $outputlangs->convToOutputCharset($object->contact->ville)."\n"; + if ($object->contact->pays_code && $object->contact->pays_code != $this->emetteur->pays_code) $carac_client.=$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$object->contact->pays_code))."\n"; + } + else + { + // Nom client + $carac_client_name=$outputlangs->convToOutputCharset($object->client->nom); + + // Nom du contact facturation si c'est une societe + $arrayidcontact = $object->getIdContact('external','SHIPPING'); + if (sizeof($arrayidcontact) > 0) + { + $object->fetch_contact($arrayidcontact[0]); + // On verifie si c'est une societe ou un particulier + if( !preg_match('#'.$object->contact->getFullName($outputlangs,1).'#isU',$object->client->nom) ) + { + $carac_client .= "\n".$outputlangs->convToOutputCharset($object->contact->getFullName($outputlangs,1,1)); + } + } + + // Caracteristiques client + $carac_client.="\n".$outputlangs->convToOutputCharset($object->client->address); + $carac_client.="\n".$outputlangs->convToOutputCharset($object->client->cp) . " " . $outputlangs->convToOutputCharset($object->client->ville)."\n"; + if ($object->client->pays_code && $object->client->pays_code != $this->emetteur->pays_code) $carac_client.=$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$object->client->pays_code))."\n"; + } + // Numero TVA intracom + if ($object->client->tva_intra) $carac_client.="\n".$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($object->client->tva_intra); + + + // Show customer/recipient + $pdf->SetXY(102,$posy+3); + $pdf->SetFont('Arial','B',11); + $pdf->MultiCell(106,4, $carac_client_name, 0, 'L'); + + $pdf->SetFont('Arial','',9); + $pdf->SetXY(102,$posy+8); + $pdf->MultiCell(86,4, $carac_client); + } + + } + + /** + * \brief Show footer of page + * \param pdf PDF factory + * \param object Object invoice + * \param outputlangs Object lang for output + * \remarks Need this->emetteur object + */ + function _pagefoot(&$pdf,$object,$outputlangs) + { + return pdf_pagefoot($pdf,$outputlangs,'DELIVERY_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object); + } + +} + +?> diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index 10570f5eb1a..52233d1ae65 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -41,8 +41,8 @@ insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) v insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (40, 'propal', 'external', 'BILLING', 'Contact client facturation propale', 1); insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (41, 'propal', 'external', 'CUSTOMER', 'Contact client suivi propale', 1); -insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (80, 'projet', 'internal', 'PROJECTLEADER', 'Chef de Projet', 1); -insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (81, 'projet', 'external', 'PROJECTLEADER', 'Chef de Projet', 1); +insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (80, 'project', 'internal', 'PROJECTLEADER', 'Chef de Projet', 1); +insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (81, 'project', 'external', 'PROJECTLEADER', 'Chef de Projet', 1); insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (50, 'facture', 'internal', 'SALESREPFOLL', 'Responsable suivi du paiement', 1); insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (60, 'facture', 'external', 'BILLING', 'Contact client facturation', 1); diff --git a/htdocs/install/mysql/migration/2.7.0-2.8.0.sql b/htdocs/install/mysql/migration/2.7.0-2.8.0.sql index 5b259d33ba7..8545659c9f9 100755 --- a/htdocs/install/mysql/migration/2.7.0-2.8.0.sql +++ b/htdocs/install/mysql/migration/2.7.0-2.8.0.sql @@ -37,3 +37,5 @@ ALTER TABLE llx_notify ADD COLUMN email VARCHAR(255); insert into llx_action_def (rowid,code,titre,description,objet_type) values (5,'NOTIFY_VAL_ORDER','Validation commande client','Executed when a customer order is validated','order'); insert into llx_action_def (rowid,code,titre,description,objet_type) values (6,'NOTIFY_VAL_PROPAL','Validation proposition client','Executed when a commercial proposal is validated','propal'); + +UPDATE llx_c_type_contact SET element='project' WHERE element='projet'; \ No newline at end of file diff --git a/htdocs/lib/project.lib.php b/htdocs/lib/project.lib.php index 956c3f50384..9417a7cec59 100644 --- a/htdocs/lib/project.lib.php +++ b/htdocs/lib/project.lib.php @@ -1,5 +1,6 @@ + * Copyright (C) 2010 Regis Houssin * * 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 @@ -23,30 +24,35 @@ * \ingroup societe * \version $Id$ */ -function project_prepare_head($objsoc) +function project_prepare_head($object) { global $langs, $conf, $user; $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/projet/fiche.php?id='.$objsoc->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/fiche.php?id='.$object->id; $head[$h][1] = $langs->trans("Project"); $head[$h][2] = 'project'; $h++; + + $head[$h][0] = DOL_URL_ROOT.'/projet/contact.php?id='.$object->id; + $head[$h][1] = $langs->trans("ProjectContact"); + $head[$h][2] = 'contact'; + $h++; - $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/fiche.php?id='.$objsoc->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/fiche.php?id='.$object->id; $head[$h][1] = $langs->trans("Tasks"); $head[$h][2] = 'tasks'; $h++; - $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/fiche.php?id='.$objsoc->id.'&mode=mine'; + $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/fiche.php?id='.$object->id.'&mode=mine'; $head[$h][1] = $langs->trans("MyTasks"); $head[$h][2] = 'mytasks'; $h++; if ($conf->propal->enabled || $conf->commande->enabled || $conf->facture->enabled) { - $head[$h][0] = DOL_URL_ROOT.'/projet/element.php?id='.$objsoc->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/element.php?id='.$object->id; $head[$h][1] = $langs->trans("Referers"); $head[$h][2] = 'element'; $h++; @@ -62,7 +68,7 @@ function project_prepare_head($objsoc) { $values=explode(':',$value); if ($values[2]) $langs->load($values[2]); - $head[$h][0] = preg_replace('/__ID__/i',$objsoc->id,$values[3]); + $head[$h][0] = preg_replace('/__ID__/i',$object->id,$values[3]); $head[$h][1] = $langs->trans($values[1]); $head[$h][2] = 'tab'.$values[1]; $h++; diff --git a/htdocs/project.class.php b/htdocs/project.class.php index dd632dd4797..c86e34a57b8 100644 --- a/htdocs/project.class.php +++ b/htdocs/project.class.php @@ -193,7 +193,7 @@ class Project extends CommonObject $this->db->free($resql); - return 0; + return 1; } else { @@ -768,11 +768,13 @@ class Project extends CommonObject // Charge tableau des id de societe socids $socids = array(); + $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."societe"; $sql.= " WHERE client IN (1, 3)"; $sql.= " AND entity = ".$conf->entity; $sql.= " LIMIT 10"; + $resql = $this->db->query($sql); if ($resql) { @@ -789,10 +791,12 @@ class Project extends CommonObject // Charge tableau des produits prodids $prodids = array(); + $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; $sql.= " WHERE envente = 1"; $sql.= " AND entity = ".$conf->entity; + $resql = $this->db->query($sql); if ($resql) { @@ -814,33 +818,18 @@ class Project extends CommonObject $socid = rand(1, $num_socs); $this->socid = $socids[$socid]; $this->date = time(); - $this->fin_validite = $this->date+3600*24*30; - $this->cond_reglement_code = 'RECEP'; - $this->mode_reglement_code = 'CHQ'; $this->note_public='SPECIMEN'; $nbp = rand(1, 9); $xnbp = 0; while ($xnbp < $nbp) { - $ligne=new PropaleLigne($this->db); + $ligne=new Task($this->db); $ligne->desc=$langs->trans("Description")." ".$xnbp; $ligne->qty=1; - $ligne->subprice=100; - $ligne->price=100; - $ligne->tva_tx=19.6; - $ligne->total_ht=100; - $ligne->total_ttc=119.6; - $ligne->total_tva=19.6; $prodid = rand(1, $num_prods); $ligne->produit_id=$prodids[$prodid]; - $this->lignes[$xnbp]=$ligne; $xnbp++; } - - $this->amount_ht = $xnbp*100; - $this->total_ht = $xnbp*100; - $this->total_tva = $xnbp*19.6; - $this->total_ttc = $xnbp*119.6; } } diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php new file mode 100644 index 00000000000..5d4b4b32950 --- /dev/null +++ b/htdocs/projet/contact.php @@ -0,0 +1,390 @@ + + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/projet/contact.php + * \ingroup project + * \brief Onglet de gestion des contacts du projet + * \version $Id$ + */ + +require ("./pre.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/project.class.php"); +require_once(DOL_DOCUMENT_ROOT."/contact.class.php"); +require_once(DOL_DOCUMENT_ROOT."/lib/project.lib.php"); +require_once(DOL_DOCUMENT_ROOT.'/html.formcompany.class.php'); + +$langs->load("projects"); +$langs->load("companies"); + +$projectid = isset($_GET["id"])?$_GET["id"]:''; + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'projet', $projectid); + + +/* + * Ajout d'un nouveau contact + */ + +if ($_POST["action"] == 'addcontact' && $user->rights->projet->creer) +{ + + $result = 0; + $project = new Project($db); + $result = $project->fetch($projectid); + + if ($result > 0 && $projectid > 0) + { + $result = $project->add_contact($_POST["contactid"], $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) + { + Header("Location: contact.php?id=".$project->id); + exit; + } + else + { + if ($project->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesg = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + } + else + { + $mesg = '
'.$project->error.'
'; + } + } +} +// modification d'un contact. On enregistre le type +if ($_POST["action"] == 'updateline' && $user->rights->projet->creer) +{ + $project = new Project($db); + if ($project->fetch($projectid)) + { + $contact = $project->detail_contact($_POST["elrowid"]); + $type = $_POST["type"]; + $statut = $contact->statut; + + $result = $project->update_contact($_POST["elrowid"], $statut, $type); + if ($result >= 0) + { + $db->commit(); + } else + { + dol_print_error($db, "result=$result"); + $db->rollback(); + } + } + else + { + dol_print_error($db); + } +} + +// bascule du statut d'un contact +if ($_GET["action"] == 'swapstatut' && $user->rights->projet->creer) +{ + $project = new Project($db); + if ($project->fetch($projectid)) + { + $contact = $project->detail_contact($_GET["ligne"]); + $id_type_contact = $contact->fk_c_type_contact; + $statut = ($contact->statut == 4) ? 5 : 4; + + $result = $project->update_contact($_GET["ligne"], $statut, $id_type_contact); + if ($result >= 0) + { + $db->commit(); + } else + { + dol_print_error($db, "result=$result"); + $db->rollback(); + } + } + else + { + dol_print_error($db); + } +} + +// Efface un contact +if ($_GET["action"] == 'deleteline' && $user->rights->projet->creer) +{ + $project = new Project($db); + $project->fetch($projectid); + $result = $project->delete_contact($_GET["lineid"]); + + if ($result >= 0) + { + Header("Location: contact.php?id=".$project->id); + exit; + } + else + { + dol_print_error($db); + } +} + + +/* + * View + */ + +llxHeader('', $langs->trans("Project"), "Project"); + +$html = new Form($db); +$formcompany= new FormCompany($db); +$contactstatic=new Contact($db); + + +/* *************************************************************************** */ +/* */ +/* Mode vue et edition */ +/* */ +/* *************************************************************************** */ +if (isset($mesg)) print $mesg; + +$id = $_GET['id']; +$ref= $_GET['ref']; +if ($id > 0 || ! empty($ref)) +{ + $project = New Project($db); + + if ( $project->fetch($id,$ref) > 0) + { + $soc = new Societe($db, $project->socid); + $soc->fetch($project->socid); + + + $head = project_prepare_head($project); + dol_fiche_head($head, 'contact', $langs->trans("Project"), 0, 'project'); + + + /* + * Projet synthese pour rappel + */ + print ''; + + //$linkback="".$langs->trans("BackToList").""; + + // Ref + print ''; + + // Customer + if ( is_null($project->client) ) + $project->fetch_client(); + print ""; + print ''; + + print "
'.$langs->trans('Ref').''; + print $html->showrefnav($project,'ref',$linkback,1,'ref','ref',''); + print '
".$langs->trans("Company")."'.$project->client->getNomUrl(1).'
"; + + print ''; + + /* + * Lignes de contacts + */ + print '
'; + + /* + * Ajouter une ligne de contact + * Non affiche en mode modification de ligne + */ + if ($_GET["action"] != 'editline' && $user->rights->projet->creer) + { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + $var = false; + + print ''; + print ''; + print ''; + print ''; + print ''; + + // Ligne ajout pour contact interne + print ""; + + print ''; + + print ''; + + print ''; + print ''; + print ''; + print ''; + + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + + // Ligne ajout pour contact externe + $var=!$var; + print ""; + + print ''; + + print ''; + + print ''; + print ''; + print ''; + print ''; + + print ""; + + print ''; + } + + // Liste des contacts lies + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + $societe = new Societe($db); + $var = true; + + foreach(array('internal','external') as $source) + { + $tab = $project->liste_contact(-1,$source); + $num=sizeof($tab); + + $i = 0; + while ($i < $num) + { + $var = !$var; + + print ''; + + // Source + print ''; + + // Societe + print ''; + + // Contact + print ''; + + // Type de contact + print ''; + + // Statut + print ''; + + // Icon update et delete + print ''; + + print "\n"; + + $i ++; + } + } + print "
'.$langs->trans("Source").''.$langs->trans("Company").''.$langs->trans("Contacts").''.$langs->trans("ContactType").' 
'; + print img_object('','user').' '.$langs->trans("Users"); + print ''; + print $conf->global->MAIN_INFO_SOCIETE_NOM; + print ''; + // On recupere les id des users deja selectionnes + $html->select_users($user->id,'contactid',0); + print ''; + $formcompany->selectTypeContact($project, '', 'type','internal'); + print '
'; + print img_object('','contact').' '.$langs->trans("ThirdPartyContacts"); + print ''; + $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$project->client->id; + $selectedCompany = $formcompany->selectCompaniesForNewContact($project, 'id', $selectedCompany, $htmlname = 'newcompany'); + print ''; + $nbofcontacts=$html->select_contacts($selectedCompany,'','contactid',0); + if ($nbofcontacts == 0) print $langs->trans("NoContactDefined"); + print ''; + $formcompany->selectTypeContact($project, '', 'type','external'); + print '
 
'.$langs->trans("Source").''.$langs->trans("Company").''.$langs->trans("Contacts").''.$langs->trans("ContactType").''.$langs->trans("Status").' 
'; + if ($tab[$i]['source']=='internal') print $langs->trans("User"); + if ($tab[$i]['source']=='external') print $langs->trans("ThirdPartyContact"); + print ''; + if ($tab[$i]['socid'] > 0) + { + print ''; + print img_object($langs->trans("ShowCompany"),"company").' '.$societe->get_nom($tab[$i]['socid']); + print ''; + } + if ($tab[$i]['socid'] < 0) + { + print $conf->global->MAIN_INFO_SOCIETE_NOM; + } + if (! $tab[$i]['socid']) + { + print ' '; + } + print ''; + if ($tab[$i]['source']=='internal') + { + print ''; + print img_object($langs->trans("ShowUser"),"user").' '.$tab[$i]['nom'].''; + } + if ($tab[$i]['source']=='external') + { + print ''; + print img_object($langs->trans("ShowContact"),"contact").' '.$tab[$i]['nom'].''; + } + print ''.$tab[$i]['libelle'].''; + // Activation desativation du contact + if ($project->statut >= 0) print ''; + print $contactstatic->LibStatut($tab[$i]['status'],3); + if ($project->statut >= 0) print ''; + print ''; + if ($user->rights->projet->creer) + { + print ' '; + print ''; + print img_delete(); + print ''; + } + print '
"; + } + else + { + print "ErrorRecordNotFound"; + } +} + +$db->close(); + +llxFooter('$Date$'); +?> \ No newline at end of file