From 2476e7bcafd3818432dfb2aab7ad2125fbeb24cf Mon Sep 17 00:00:00 2001 From: Florian Henry Date: Wed, 17 Jul 2013 18:45:58 +0200 Subject: [PATCH 1/4] Start functionnality --- htdocs/core/modules/modProjet.class.php | 22 ++ htdocs/projet/admin/project.php | 324 ++++++++++++++++++++++++ htdocs/projet/tasks/task.php | 73 +++++- 3 files changed, 418 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index e5f956b0946..1cc0d091778 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -92,6 +93,27 @@ class modProjet extends DolibarrModules $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/projects"; $this->const[$r][3] = ""; $this->const[$r][4] = 0; + + $this->const[$r][0] = "PROJECT_TASK_ADDON_PDF"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "baleine"; + $this->const[$r][3] = 'Nom du gestionnaire de generation des task en PDF'; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "PROJECT_TASK_ADDON"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "mod_task_simple"; + $this->const[$r][3] = 'Nom du gestionnaire de numerotation des taches'; + $this->const[$r][4] = 0; + $r++; + + $r++; + $this->const[$r][0] = "PROJECT_TASK_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/tasks"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; // Boxes $this->boxes = array(); diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index 036c2fae18b..d70a801ab2e 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -113,6 +113,51 @@ else if ($action == 'specimen') } } +else if ($action == 'specimentask') +{ + $modele=GETPOST('module','alpha'); + + $project = new Project($db); + $project->initAsSpecimen(); + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/project/task/pdf/pdf_".$modele.".modules.php",0); + if (file_exists($file)) + { + $filefound=1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($project,$langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project_task&file=SPECIMEN.pdf"); + return; + } + else + { + $mesg='
'.$obj->error.'
'; + dol_syslog($obj->error, LOG_ERR); + } + } + else + { + $mesg='
'.$langs->trans("ErrorModuleNotFound").'
'; + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + // Activate a model else if ($action == 'set') { @@ -127,6 +172,14 @@ else if ($action == 'del') if ($conf->global->PROJECT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_ADDON_PDF',$conf->entity); } } +if ($action == 'deltask') +{ + $ret = delDocumentModel($value, 'project_task'); + if ($ret > 0) + { + if ($conf->global->PROJECT_TASK_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_TASK_ADDON_PDF',$conf->entity); + } +} // Set default model else if ($action == 'setdoc') @@ -146,6 +199,23 @@ else if ($action == 'setdoc') } } +else if ($action == 'setdoctask') +{ + if (dolibarr_set_const($db, "PROJECT_TASK_ADDON_PDF",$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->PROJECT_TASK_ADDON_PDF = $value; + } + + // On active le modele + $ret = delDocumentModel($value, 'project_task'); + if ($ret > 0) + { + $ret = addDocumentModel($value, 'project_task', $label, $scandir); + } +} + else if ($action == 'setmod') { // TODO Verifier si module numerotation choisi peut etre active @@ -154,6 +224,14 @@ else if ($action == 'setmod') dolibarr_set_const($db, "PROJECT_ADDON",$value,'chaine',0,'',$conf->entity); } +else if ($action == 'setmodtask') +{ + // TODO Verifier si module numerotation choisi peut etre active + // par appel methode canBeActivated + + dolibarr_set_const($db, "PROJECT_TASK_ADDON",$value,'chaine',0,'',$conf->entity); +} + else if ($action=='setModuleOptions') { if (dolibarr_set_const($db, "PROJECT_ADDON_PDF_ODT_PATH",GETPOST('value1'),'chaine',0,'',$conf->entity)) { @@ -162,6 +240,15 @@ else if ($action=='setModuleOptions') { $conf->global->PROJECT_ADDON_PDF_ODT_PATH = GETPOST('value1'); } } + +else if ($action=='setModuleOptionsTask') { + if (dolibarr_set_const($db, "PROJECT_TASK_ADDON_PDF_ODT_PATH",GETPOST('value1'),'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->PROJECT_TASK_ADDON_PDF_ODT_PATH = GETPOST('value1'); + } +} /* * View */ @@ -285,6 +372,106 @@ foreach ($dirmodels as $reldir) print '
'; +// Task numbering module +print_titre($langs->trans("TasksNumberingModules")); + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/project/task/"); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + $var=true; + + while (($file = readdir($handle))!==false) + { + if (preg_match('/^(mod_.*)\.php$/i',$file,$reg)) + { + $file = $reg[1]; + $classname = substr($file,4); + + require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$file.'.php'; + + $module = new $file; + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) + { + $var=!$var; + print ''; + + // Show example of numbering module + print ''."\n"; + + print ''; + + $project=new Project($db); + $project->initAsSpecimen(); + + // Info + $htmltooltip=''; + $htmltooltip.=''.$langs->trans("Version").': '.$module->getVersion().'
'; + $nextval=$module->getNextValue($mysoc,$project); + if ("$nextval" != $langs->trans("NotAvailable")) // Keep " on nextval + { + $htmltooltip.=''.$langs->trans("NextValue").': '; + if ($nextval) + { + $htmltooltip.=$nextval.'
'; + } + else + { + $htmltooltip.=$langs->trans($module->error).'
'; + } + } + + print ''; + + print ''; + } + } + } + closedir($handle); + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Activated").''.$langs->trans("Infos").'
'.$module->nom."\n"; + print $module->info(); + print ''; + $tmp=$module->getExample(); + if (preg_match('/^Error/',$tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp=='NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->PROJECT_TASK_ADDON == 'mod_'.$classname) + { + print img_picto($langs->trans("Activated"),'switch_on'); + } + else + { + print ''.img_picto($langs->trans("Disabled"),'switch_off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print '

'; /* * Document templates generators @@ -412,6 +599,143 @@ foreach ($dirmodels as $reldir) } print ''; + print "\n"; + } + } + } + } + closedir($handle); + } + } +} + +print '
'; + +/* + * Modeles documents for Task +*/ + +print_titre($langs->trans("TaskModelModule")); + +// Defini tableau def de modele +$type='project_task'; +$def = array(); + +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; + +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + +print "\n"; +print "\n"; +print ' \n"; +print " \n"; +print '\n"; +print '\n"; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/project/task/pdf/"); + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print '\n"; + + // Active + if (in_array($name, $def)) + { + print ""; + } + else + { + print ""; + } + + // Defaut + print "'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + + // Preview + print ''; print "\n"; } } diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 858e4612f1a..bb5995ce67c 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -31,6 +31,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +$langs->load("projects"); +$langs->load("companies"); + $id=GETPOST('id','int'); $ref=GETPOST('ref','alpha'); $action=GETPOST('action','alpha'); @@ -38,6 +41,8 @@ $confirm=GETPOST('confirm','alpha'); $withproject=GETPOST('withproject','int'); $project_ref=GETPOST('project_ref','alpha'); $planned_workload=GETPOST('planned_workloadhour'); +$taskid = GETPOST("id",'int'); +$taskref = GETPOST("ref",'int'); // Security check $socid=0; @@ -134,16 +139,63 @@ if (! empty($project_ref) && ! empty($withproject)) } } +// Build doc +if ($action == 'builddoc' && $user->rights->projet->creer) +{ + if ($object->fetch($id) >= 0 ) + { + if (GETPOST('model')) + { + $object->setDocModel($user, GETPOST('model')); + } + + $outputlangs = $langs; + if (GETPOST('lang_id')) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang(GETPOST('lang_id')); + } + $result=task_pdf_create($db, $object, $object->modelpdf, $outputlangs); + 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; + } + } +} + +// Delete file in doc form +if ($action == 'remove_file' && $user->rights->projet->creer) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + if ($object->fetch($id) >= 0 ) + { + $langs->load("other"); + $upload_dir = $conf->projet->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + + $ret=dol_delete_file($file); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + } +} + /* * View */ -$langs->load('projects'); llxHeader('', $langs->trans("Task")); $form = new Form($db); $formother = new FormOther($db); +$formfile = new FormFile($db); if ($id > 0 || ! empty($ref)) { @@ -434,6 +486,25 @@ if ($id > 0 || ! empty($ref)) } print ''; + + print '
'.$langs->trans("Name")."".$langs->trans("Description")."'.$langs->trans("Activated")."'.$langs->trans("Default")."'.$langs->trans("Infos").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print ""; + if ($conf->global->PROJECT_TASK_ADDON_PDF == "$name") + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'bill').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; + print ''; // ancre + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($projectstatic->ref). "/". dol_sanitizeFileName($object->ref); + $filedir=$conf->projet->dir_output . "/" . dol_sanitizeFileName($projectstatic->ref). "/" .dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed=($user->rights->projet->lire); + $delallowed=($user->rights->projet->creer); + + $var=true; + + $somethingshown=$formfile->show_documents('project_task',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf); + + + print '
'; } } } From ee82330292ee74b4e2522140623476770692bc53 Mon Sep 17 00:00:00 2001 From: Florian Henry Date: Wed, 17 Jul 2013 19:17:54 +0200 Subject: [PATCH 2/4] On going sync/merge from other repo --- .../modules/project/task/mod_task_simple.php | 152 ++++ .../project/task/mod_task_universal.php | 142 +++ .../modules/project/task/modules_task.php | 252 ++++++ .../task/pdf/doc_generic_task_odt.modules.php | 844 ++++++++++++++++++ .../tasks/template_task_summary.odt | Bin 0 -> 21249 bytes htdocs/projet/admin/project.php | 19 + 6 files changed, 1409 insertions(+) create mode 100644 htdocs/core/modules/project/task/mod_task_simple.php create mode 100644 htdocs/core/modules/project/task/mod_task_universal.php create mode 100644 htdocs/core/modules/project/task/modules_task.php create mode 100644 htdocs/core/modules/project/task/pdf/doc_generic_task_odt.modules.php create mode 100644 htdocs/install/doctemplates/tasks/template_task_summary.odt diff --git a/htdocs/core/modules/project/task/mod_task_simple.php b/htdocs/core/modules/project/task/mod_task_simple.php new file mode 100644 index 00000000000..25cc347bcf9 --- /dev/null +++ b/htdocs/core/modules/project/task/mod_task_simple.php @@ -0,0 +1,152 @@ + + * Copyright (C) 2010 Laurent Destailleur + * + * 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/project/mod_project_simple.php + * \ingroup project + * \brief File with class to manage the numbering module Simple for project references + */ + +require_once DOL_DOCUMENT_ROOT .'/core/modules/project/task/modules_task.php'; + + +/** + * Class to manage the numbering module Simple for project references + */ +class mod_task_simple extends ModeleNumRefTask +{ + var $version='dolibarr'; // 'development', 'experimental', 'dolibarr' + var $prefix='TK'; + var $error=''; + var $nom = "Simple"; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc",$this->prefix); + } + + + /** + * Return an example of numbering module values + * + * @return string Example + */ + function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** 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() + { + global $conf,$langs; + + $coyymm=''; $max=''; + + $posindice=8; + $sql = "SELECT MAX(SUBSTRING(ref FROM ".$posindice.")) as max"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task"; + $sql.= " WHERE ref LIKE '".$this->prefix."____-%'"; + $sql.= " AND entity = ".$conf->entity; + $resql=$db->query($sql); + if ($resql) + { + $row = $db->fetch_row($resql); + if ($row) { $coyymm = substr($row[0],0,6); $max=$row[0]; } + } + if (! $coyymm || preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i',$coyymm)) + { + return true; + } + else + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorNumRefModel',$max); + return false; + } + } + + + /** + * Return next value + * + * @param Societe $objsoc Object third party + * @param Task $Task Object Task + * @return string Value if OK, 0 if KO + */ + function getNextValue($objsoc,$task) + { + global $db,$conf; + + // D'abord on recupere la valeur max + $posindice=8; + $sql = "SELECT MAX(SUBSTRING(ref FROM ".$posindice.")) as max"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task"; + $sql.= " WHERE ref like '".$this->prefix."____-%'"; + + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max=0; + } + else + { + dol_syslog("mod_task_simple::getNextValue sql=".$sql); + return -1; + } + + $date=empty($task->date_c)?dol_now():$task->date_c; + + //$yymm = strftime("%y%m",time()); + $yymm = strftime("%y%m",$date); + $num = sprintf("%04s",$max+1); + + dol_syslog("mod_task_simple::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } + + + /** + * Return next reference not yet used as a reference + * + * @param Societe $objsoc Object third party + * @param Task $task Object task + * @return string Next not used reference + */ + function task_get_num($objsoc=0,$task='') + { + return $this->getNextValue($objsoc,$task); + } +} + +?> \ No newline at end of file diff --git a/htdocs/core/modules/project/task/mod_task_universal.php b/htdocs/core/modules/project/task/mod_task_universal.php new file mode 100644 index 00000000000..2e660bd9cdb --- /dev/null +++ b/htdocs/core/modules/project/task/mod_task_universal.php @@ -0,0 +1,142 @@ + + * + * 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/project/mod_project_universal.php + * \ingroup project + * \brief Fichier contenant la classe du modele de numerotation de reference de projet Universal + */ + +require_once DOL_DOCUMENT_ROOT .'/core/modules/project/task/modules_task.php'; + + +/** + * Classe du modele de numerotation de reference de projet Universal + */ +class mod_task_universal extends ModeleNumRefTask +{ + var $version='dolibarr'; // 'development', 'experimental', 'dolibarr' + var $error = ''; + var $nom = 'Universal'; + + + /** + * 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($this->db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + $tooltip=$langs->trans("GenericMaskCodes",$langs->transnoentities("Task"),$langs->transnoentities("Task")); + $tooltip.=$langs->trans("GenericMaskCodes2"); + $tooltip.=$langs->trans("GenericMaskCodes3"); + $tooltip.=$langs->trans("GenericMaskCodes4a",$langs->transnoentities("Task"),$langs->transnoentities("Task")); + $tooltip.=$langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte.= ''; + $texte.= ''; + + $texte.= ''; + + $texte.= ''; + + $texte.= '
'.$langs->trans("Mask").':'.$form->textwithpicto('',$tooltip,1,1).' 
'; + $texte.= '
'; + + return $texte; + } + + /** + * 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; + } + + /** + * Return next value + * + * @param Societe $objsoc Object third party + * @param Project $project Object project + * @return string Value if OK, 0 if KO + */ + function getNextValue($objsoc,$project) + { + global $db,$conf; + + require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php'; + + // On defini critere recherche compteur + $mask=$conf->global->PROJECT_TASK_UNIVERSAL_MASK; + + if (! $mask) + { + $this->error='NotConfigured'; + return 0; + } + + $date=empty($project->date_c)?dol_now():$project->date_c; + $numFinal=get_next_value($db,$mask,'projet_task','ref','',$objsoc->code_client,$date); + + return $numFinal; + } + + + /** + * Return next reference not yet used as a reference + * + * @param Societe $objsoc Object third party + * @param Project $project Object project + * @return string Next not used reference + */ + function project_get_num($objsoc=0,$project='') + { + return $this->getNextValue($objsoc,$project); + } +} + +?> \ No newline at end of file diff --git a/htdocs/core/modules/project/task/modules_task.php b/htdocs/core/modules/project/task/modules_task.php new file mode 100644 index 00000000000..824c5d12152 --- /dev/null +++ b/htdocs/core/modules/project/task/modules_task.php @@ -0,0 +1,252 @@ + + * Copyright (C) 2010 Florian Henry + * + * 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/project/task/modules_task.php + * \ingroup project + * \brief File that contain parent class for task models + * and parent class for task numbering models + */ +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + + +/** + * Parent class for projects models + */ +abstract class ModelePDFTask extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='project_task'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + + return $liste; + } +} + + + +/** + * Classe mere des modeles de numerotation des references de projets + */ +abstract class ModeleNumRefTask +{ + var $error=''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + function isEnabled() + { + return true; + } + + /** + * Renvoi la description par defaut du modele de numerotation + * + * @return string Texte descripif + */ + function info() + { + global $langs; + $langs->load("projects"); + return $langs->trans("NoDescription"); + } + + /** + * Renvoi un exemple de numerotation + * + * @return string Example + */ + function getExample() + { + global $langs; + $langs->load("projects"); + return $langs->trans("NoExample"); + } + + /** + * 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; + } + + /** + * Renvoi prochaine valeur attribuee + * + * @param Societe $objsoc Object third party + * @param Project $project Object project + * @return string Valeur + */ + function getNextValue($objsoc, $project) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * 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"); + } +} + + +/** + * Create an intervention document on disk using template defined into PROJECT_TASK_ADDON_PDF + * + * @param DoliDB $db objet base de donnee + * @param Object $object Object fichinter + * @param string $modele force le modele a utiliser ('' par defaut) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param HookManager $hookmanager Hook manager instance + * @return int 0 if KO, 1 if OK + */ +function task_pdf_create($db, $object, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $hookmanager=false) +{ + global $conf,$langs; + $langs->load("projects"); + + $error=0; + + $srctemplatepath=''; + + // Positionne modele sur le nom du modele de projet a utiliser + if (! dol_strlen($modele)) + { + if (! empty($conf->global->PROJECT_TASK_ADDON_PDF)) + { + $modele = $conf->global->PROJECT_TASK_ADDON_PDF; + } + else + { + $modele='baleine'; + } + } + + // If selected modele is a filename template (then $modele="modelname:filename") + $tmp=explode(':',$modele,2); + if (! empty($tmp[1])) + { + $modele=$tmp[0]; + $srctemplatepath=$tmp[1]; + } + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array('/'); + if (is_array($conf->modules_parts['models'])) $dirmodels=array_merge($dirmodels,$conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + foreach(array('doc','pdf') as $prefix) + { + $file = $prefix."_".$modele.".modules.php"; + + // On verifie l'emplacement du modele + $file=dol_buildpath($reldir."core/modules/project/task/pdf/".$file,0); + if (file_exists($file)) + { + $filefound=1; + $classname=$prefix.'_'.$modele; + break; + } + } + if ($filefound) break; + } + + // Charge le modele + if ($filefound) + { + require_once $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($object, $outputlangs, $srctemplatepath, $hidedetails, $hidedesc, $hideref, $hookmanager) > 0) + { + $outputlangs->charset_output=$sav_charset_output; + + // we delete preview files + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_delete_preview($object); + + // Success in building document. We build meta file. + dol_meta_create($object); + + // Appel des triggers + /*include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('PROJECT_BUILDDOC',$object,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; }*/ + // Fin appel triggers + + return 1; + } + else + { + $outputlangs->charset_output=$sav_charset_output; + dol_print_error($db,"task_pdf_create Error: ".$obj->error); + return 0; + } + } + else + { + print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file); + return 0; + } +} + +?> \ No newline at end of file diff --git a/htdocs/core/modules/project/task/pdf/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/pdf/doc_generic_task_odt.modules.php new file mode 100644 index 00000000000..3a9c86bdb09 --- /dev/null +++ b/htdocs/core/modules/project/task/pdf/doc_generic_task_odt.modules.php @@ -0,0 +1,844 @@ + + * Copyright (C) 2012 Juanjo Menent +* Copyright (C) 2013 Florian Henry +* +* 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/project/task/pdf/doc_generic_task_odt.modules.php + * \ingroup project + * \brief File of class to build ODT documents for third parties +*/ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; +require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; +if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; +if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_task_odt extends ModelePDFTask +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 0; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'etait pas defini + } + + + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + * @return array Array of substitution + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; + + return array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_title'=>$object->title, + 'object_description'=>$object->description, + 'object_date_creation'=>dol_print_date($object->date_c,'day'), + 'object_date_modification'=>dol_print_date($object->date_m,'day'), + 'object_date_start'=>dol_print_date($object->date_start,'day'), + 'object_date_end'=>dol_print_date($object->date_end,'day'), + 'object_note_private'=>$object->note_private, + 'object_note_public'=>$object->note_public, + 'object_public'=>$object->public, + 'object_statut'=>$object->getLibStatut() + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $task Task Object + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_tasks($task,$outputlangs) + { + global $conf; + + return array( + 'task_ref'=>$task->ref, + 'task_fk_project'=>$task->fk_project, + 'task_projectref'=>$task->projectref, + 'task_projectlabel'=>$task->projectlabel, + 'task_label'=>$task->label, + 'task_description'=>$task->description, + 'task_fk_parent'=>$task->fk_parent, + 'task_duration'=>$task->duration, + 'task_progress'=>$task->progress, + 'task_public'=>$task->public, + 'task_date_start'=>dol_print_date($task->date_start,'day'), + 'task_date_end'=>dol_print_date($task->date_end,'day'), + 'task_note_private'=>$task->note_private, + 'task_note_public'=>$task->note_public + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $contact Contact array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_contacts($contact,$outputlangs) + { + global $conf; + + return array( + 'projcontacts_id'=>$contact['id'], + 'projcontacts_rowid'=>$contact['rowid'], + 'projcontacts_role'=>$contact['libelle'], + 'projcontacts_lastname'=>$contact['lastname'], + 'projcontacts_firstname'=>$contact['firstname'], + 'projcontacts_fullcivname'=>$contact['fullname'], + 'projcontacts_socname'=>$contact['socname'], + 'projcontacts_email'=>$contact['email'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $file file array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_file($file,$outputlangs) + { + global $conf; + + return array( + 'projfile_name'=>$file['name'], + 'projfile_date'=>dol_print_date($file['date'],'day'), + 'projfile_size'=>$file['size'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $refdetail Reference array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_reference($refdetail,$outputlangs) + { + global $conf; + + return array( + 'projref_type'=>$refdetail['type'], + 'projref_ref'=>$refdetail['ref'], + 'projref_date'=>dol_print_date($refdetail['date'],'day'), + 'projref_socname'=>$refdetail['socname'], + 'projref_amountht'=>price($refdetail['amountht'],0,$outputlangs), + 'projref_amountttc'=>price($refdetail['amountttc'],0,$outputlangs), + 'projref_status'=>$refdetail['status'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $taskressource Reference array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_tasksressource($taskressource,$outputlangs) + { + global $conf; + //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG); + return array( + 'taskressource_rowid'=>$taskressource['rowid'], + 'taskressource_role'=>$taskressource['libelle'], + 'taskressource_lastname'=>$taskressource['lastname'], + 'taskressource_firstname'=>$taskressource['firstname'], + 'taskressource_fullcivname'=>$taskressource['fullname'], + 'taskressource_socname'=>$taskressource['socname'], + 'taskressource_email'=>$taskressource['email'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param object $tasktime times object + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_taskstime($tasktime,$outputlangs) + { + global $conf; + + return array( + 'tasktime_rowid'=>$tasktime['rowid'], + 'tasktime_task_date'=>dol_print_date($tasktime['task_date'],'day'), + 'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'],'all'), + 'tasktime_note'=>$tasktime['note'], + 'tasktime_fk_user'=>$tasktime['fk_user'], + 'tasktime_user_name'=>$tasktime['name'], + 'tasktime_user_first'=>$tasktime['firstname'], + 'tasktime_fullcivname'=>$tasktime['fullcivname'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $file file array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_task_file($file,$outputlangs) + { + global $conf; + + return array( + 'tasksfile_name'=>$file['name'], + 'tasksfile_date'=>dol_print_date($file['date'],'day'), + 'tasksfile_size'=>$file['size'] + ); + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + // List of directories area + $texte.= ''; + + + $texte.= ''; + $texte.= ''; + + /*$texte.= ''; + $texte.= ''; + $texte.= '';*/ + + $texte.= '
'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '
'; + $texte.= ''; + $texte.= '  '; + $texte.= ''; + $texte.= '
'; + + // Scan directories + if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + $texte.= '
'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + $texte.= '
'; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Commande $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath) + { + global $user,$langs,$conf,$mysoc; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $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 Task($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + $project= new Project($this->db); + $project->fetch($object->fk_project); + + $dir = $conf->projet->dir_output. "/" . $project->ref. "/";; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + print '$dir'.$dir; + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + $file=$dir.'/'.$newfiletmp.'.odt'; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->projet->dir_temp); + + $socobject=$object->thirdparty; + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + ); + complete_substitutions_array($substitutionarray, $langs, $object); + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->projet->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + + + // Make substitutions into odt of user info + $tmparray=$this->get_substitutionarray_user($user,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Make substitutions into odt of thirdparty + $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + $odfHandler->setVarsHeadFooter($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_object($project,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of lines for tasks + try + { + // Security check + $socid=0; + if (!empty($project->fk_soc)) $socid = $project->fk_soc; + + $tmparray=$this->get_substitutionarray_tasks($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $task); + foreach($tmparray as $key => $val) + { + try + { + $odfHandler->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + + // Replace tags of lines for contacts task + $sourcearray=array('internal','external'); + $contact_arrray=array(); + foreach ($sourcearray as $source) { + $contact_temp=$object->liste_contact(-1,$source); + if ((is_array($contact_temp) && count($contact_temp) > 0)) + { + $contact_arrray=array_merge($contact_arrray,$contact_temp); + } + } + if ((is_array($contact_arrray) && count($contact_arrray) > 0)) + { + $listlinestaskres = $odfHandler->setSegment('tasksressources'); + + foreach ($contact_arrray as $contact) + { + if ($contact['source']=='internal') { + $objectdetail=new User($this->db); + $objectdetail->fetch($contact['id']); + $contact['socname']=$mysoc->name; + } elseif ($contact['source']=='external') { + $objectdetail=new Contact($this->db); + $objectdetail->fetch($contact['id']); + + $soc=new Societe($this->db); + $soc->fetch($contact['socid']); + $contact['socname']=$soc->name; + } + $contact['fullname']=$objectdetail->getFullName($outputlangs,1); + + $tmparray=$this->get_substitutionarray_tasksressource($contact,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlinestaskres->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlinestaskres->merge(); + } + $odfHandler->mergeSegment($listlinestaskres); + } + + //Time ressources + $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; + $sql.= ", u.name, u.firstname"; + $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql .= " , ".MAIN_DB_PREFIX."user as u"; + $sql .= " WHERE t.fk_task =".$object->id; + $sql .= " AND t.fk_user = u.rowid"; + $sql .= " ORDER BY t.task_date DESC"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + $tasks = array(); + $listlinestasktime = $odfHandler->setSegment('taskstimes'); + while ($i < $num) + { + $row = $this->db->fetch_array($resql); + if (!empty($row['fk_user'])) { + $objectdetail=new User($this->db); + $objectdetail->fetch($row['fk_user']); + $row['fullcivname']=$objectdetail->getFullName($outputlangs,1); + } else { + $row['fullcivname']=''; + } + + $tmparray=$this->get_substitutionarray_taskstime($row,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlinestasktime->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlinestasktime->merge(); + $i++; + } + $this->db->free($resql); + + $odfHandler->mergeSegment($listlinestasktime); + } + + + // Replace tags of project files + $listtasksfiles = $odfHandler->setSegment('tasksfiles'); + + $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref); + $filearray=dol_dir_list($upload_dir,"files",0,'','\.meta$','name',SORT_ASC,1); + + + foreach ($filearray as $filedetail) + { + $tmparray=$this->get_substitutionarray_task_file($filedetail,$outputlangs); + //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true)); + foreach($tmparray as $key => $val) + { + try + { + $listtasksfiles->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listtasksfiles->merge(); + } + //$listlines->merge(); + + $odfHandler->mergeSegment($listtasksfiles); + + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + + + // Replace tags of project files + try + { + $listlines = $odfHandler->setSegment('projectfiles'); + + $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($object->ref); + $filearray=dol_dir_list($upload_dir,"files",0,'','\.meta$','name',SORT_ASC,1); + + + foreach ($filearray as $filedetail) + { + //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true)); + $tmparray=$this->get_substitutionarray_project_file($filedetail,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace tags of lines for contacts + $sourcearray=array('internal','external'); + $contact_arrray=array(); + foreach ($sourcearray as $source) { + $contact_temp=$project->liste_contact(-1,$source); + if ((is_array($contact_temp) && count($contact_temp) > 0)) + { + $contact_arrray=array_merge($contact_arrray,$contact_temp); + } + } + if ((is_array($contact_arrray) && count($contact_arrray) > 0)) + { + try + { + $listlines = $odfHandler->setSegment('projectcontacts'); + + foreach ($contact_arrray as $contact) + { + if ($contact['source']=='internal') { + $objectdetail=new User($this->db); + $objectdetail->fetch($contact['id']); + $contact['socname']=$mysoc->name; + } elseif ($contact['source']=='external') { + $objectdetail=new Contact($this->db); + $objectdetail->fetch($contact['id']); + + $soc=new Societe($this->db); + $soc->fetch($contact['socid']); + $contact['socname']=$soc->name; + } + $contact['fullname']=$objectdetail->getFullName($outputlangs,1); + + $tmparray=$this->get_substitutionarray_project_contacts($contact,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + } + + + // Write new file + $odfHandler->saveToDisk($file); + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} +?> \ No newline at end of file diff --git a/htdocs/install/doctemplates/tasks/template_task_summary.odt b/htdocs/install/doctemplates/tasks/template_task_summary.odt new file mode 100644 index 0000000000000000000000000000000000000000..76984ebcf8cb915a336d598a1899aa10abed260f GIT binary patch literal 21249 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 literal 0 HcmV?d00001 diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index d70a801ab2e..c0cc144861c 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -68,6 +68,25 @@ if ($action == 'updateMask') } } +if ($action == 'updateMaskTask') +{ + $maskconstmasktask=GETPOST('maskconsttask','alpha'); + $masktaskt=GETPOST('masktask','alpha'); + + if ($maskconstmasktask) $res = dolibarr_set_const($db,$maskconstmasktask,$masktaskt,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + $mesg = "".$langs->trans("SetupSaved").""; + } + else + { + $mesg = "".$langs->trans("Error").""; + } +} + else if ($action == 'specimen') { $modele=GETPOST('module','alpha'); From 0c0a64f532acab66844e23dda75647d08d647386 Mon Sep 17 00:00:00 2001 From: Florian Henry Date: Thu, 18 Jul 2013 10:24:45 +0200 Subject: [PATCH 3/4] [ task #924 ] Add numbering rule on task [ task #925 ] Add ODT document generation for Tasks in project module --- htdocs/core/class/html.formfile.class.php | 9 ++++ htdocs/core/lib/project.lib.php | 4 +- htdocs/core/modules/modProjet.class.php | 10 ++-- htdocs/install/etape1.php | 2 +- .../install/mysql/migration/3.4.0-3.5.0.sql | 8 ++++ .../install/mysql/tables/llx_projet_task.sql | 7 +-- htdocs/langs/en_US/admin.lang | 2 + htdocs/langs/fr_FR/admin.lang | 2 + htdocs/projet/admin/project.php | 5 ++ htdocs/projet/class/task.class.php | 48 +++++++++++++++---- htdocs/projet/tasks.php | 20 +++++++- htdocs/projet/tasks/task.php | 21 ++++---- 12 files changed, 110 insertions(+), 28 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 9290c9873bf..78bf317d3a9 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -309,6 +309,15 @@ class FormFile $modellist=ModelePDFProjects::liste_modeles($this->db); } } + elseif ($modulepart == 'project_task') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php'; + $modellist=ModelePDFTask::liste_modeles($this->db); + } + } elseif ($modulepart == 'export') { if (is_array($genallowed)) $modellist=$genallowed; diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index e5ea867d0a7..52978d65349 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -281,12 +281,12 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''; if ($showlineingray) { - print ''.img_object('','projecttask').' '.$lines[$i]->id.''; + print ''.img_object('','projecttask').' '.$lines[$i]->ref.''; } else { $taskstatic->id=$lines[$i]->id; - $taskstatic->ref=$lines[$i]->id; + $taskstatic->ref=$lines[$i]->ref; $taskstatic->label=($taskrole[$lines[$i]->id]?$langs->trans("YourRole").': '.$taskrole[$lines[$i]->id]:''); print $taskstatic->getNomUrl(1,($showproject?'':'withproject')); } diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 1cc0d091778..7b9ec52aef6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -76,14 +76,14 @@ class modProjet extends DolibarrModules $this->const[$r][0] = "PROJECT_ADDON_PDF"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "baleine"; - $this->const[$r][3] = 'Nom du gestionnaire de generation des projets en PDF'; + $this->const[$r][3] = 'Name of PDF/ODT project manager class'; $this->const[$r][4] = 0; $r++; $this->const[$r][0] = "PROJECT_ADDON"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "mod_project_simple"; - $this->const[$r][3] = 'Nom du gestionnaire de numerotation des projets'; + $this->const[$r][3] = 'Name of Numbering Rule project manager class'; $this->const[$r][4] = 0; $r++; @@ -96,15 +96,15 @@ class modProjet extends DolibarrModules $this->const[$r][0] = "PROJECT_TASK_ADDON_PDF"; $this->const[$r][1] = "chaine"; - $this->const[$r][2] = "baleine"; - $this->const[$r][3] = 'Nom du gestionnaire de generation des task en PDF'; + $this->const[$r][2] = ""; + $this->const[$r][3] = 'Name of PDF/ODT tasks manager class'; $this->const[$r][4] = 0; $r++; $this->const[$r][0] = "PROJECT_TASK_ADDON"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "mod_task_simple"; - $this->const[$r][3] = 'Nom du gestionnaire de numerotation des taches'; + $this->const[$r][3] = 'Name of Numbering Rule task manager class'; $this->const[$r][4] = 0; $r++; diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 36b26fd7953..f1aba6f52c2 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -402,7 +402,7 @@ if (! $error && $db->connected && $action == "set") require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $srcroot=$main_dir.'/install/doctemplates'; $destroot=$main_data_dir.'/doctemplates'; - $docs=array('thirdparties' => 'thirdparty', 'proposals' => 'proposal', 'orders' => 'order', 'invoices' => 'invoice', 'projects' => 'project', 'projects' => 'task_summary'); + $docs=array('thirdparties' => 'thirdparty', 'proposals' => 'proposal', 'orders' => 'order', 'invoices' => 'invoice', 'projects' => 'project', 'projects' => 'task_summary', 'tasks' => 'task_summary'); foreach($docs as $cursordir => $cursorfile) { $src=$srcroot.'/'.$cursordir.'/template_'.$cursorfile.'.odt'; diff --git a/htdocs/install/mysql/migration/3.4.0-3.5.0.sql b/htdocs/install/mysql/migration/3.4.0-3.5.0.sql index e55f063ab15..7e1f4086dd7 100755 --- a/htdocs/install/mysql/migration/3.4.0-3.5.0.sql +++ b/htdocs/install/mysql/migration/3.4.0-3.5.0.sql @@ -90,4 +90,12 @@ ALTER TABLE llx_categorie_contact ADD INDEX idx_categorie_contact_fk_socpeople ( ALTER TABLE llx_categorie_contact ADD CONSTRAINT fk_categorie_contact_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); ALTER TABLE llx_categorie_contact ADD CONSTRAINT fk_categorie_contact_fk_socpeople FOREIGN KEY (fk_socpeople) REFERENCES llx_socpeople (rowid); +insert into llx_const (name, value, type, note, visible, entity) values ('PROJECT_TASK_ADDON_PDF','','chaine','Name of PDF/ODT tasks manager class',0,1); +insert into llx_const (name, value, type, note, visible, entity) values ('PROJECT_TASK_ADDON','mod_task_simple','chaine','Name of Numbering Rule task manager class',0,1); +insert into llx_const (name, value, type, note, visible, entity) values ('PROJECT_TASK_ADDON_PDF_ODT_PATH','DOL_DATA_ROOT/doctemplates/tasks','chaine','',0,1); + +ALTER TABLE llx_projet_task ADD COLUMN ref varchar(50) AFTER rowid; +UPDATE llx_projet_task SET ref=rowid; +ALTER TABLE llx_projet_task ADD COLUMN model_pdf varchar(255); + diff --git a/htdocs/install/mysql/tables/llx_projet_task.sql b/htdocs/install/mysql/tables/llx_projet_task.sql index 1fc7325bea0..0c91a86b1a8 100644 --- a/htdocs/install/mysql/tables/llx_projet_task.sql +++ b/htdocs/install/mysql/tables/llx_projet_task.sql @@ -29,8 +29,8 @@ create table llx_projet_task datev datetime, -- date validation label varchar(255) NOT NULL, description text, - duration_effective real DEFAULT 0 NOT NULL, - planned_workload real DEFAULT 0 NOT NULL, + duration_effective real DEFAULT 0 NOT NULL, + planned_workload real DEFAULT 0 NOT NULL, progress integer DEFAULT 0, -- percentage increase priority integer DEFAULT 0, -- priority fk_user_creat integer, -- user who created the task @@ -38,5 +38,6 @@ create table llx_projet_task fk_statut smallint DEFAULT 0 NOT NULL, note_private text, note_public text, - rang integer DEFAULT 0 + rang integer DEFAULT 0, + model_pdf varchar(255) )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 80f2d76557b..34f04575546 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1454,6 +1454,8 @@ TestGeoIPResult=Test of a conversion IP -> country ProjectsNumberingModules=Projects numbering module ProjectsSetup=Project module setup ProjectsModelModule=Project reports document model +TasksNumberingModules=Tasks numbering module +TaskModelModule=Tasks reports document model ##### ECM (GED) ##### ECMSetup = GED Setup ECMAutoTree = Automatic tree folder and document diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index a057e02944c..1f4be3a3722 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1454,6 +1454,8 @@ TestGeoIPResult=Test de conversion IP -> Pays ProjectsNumberingModules=Modèles de numérotation des références projets ProjectsSetup=Configuration du module Projets ProjectsModelModule=Modèles de document de rapport projets +TasksNumberingModules==Modèles de numérotation des références taches +TaskModelModule=Modèles de document de rapport taches ##### ECM (GED) ##### ECMSetup = Configuration du module GED ECMAutoTree = L'arborescence automatique est disponible diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index c0cc144861c..136e5124ca5 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -182,6 +182,11 @@ else if ($action == 'set') { $ret = addDocumentModel($value, $type, $label, $scandir); } +// Activate a model for task +else if ($action == 'settask') +{ + $ret = addDocumentModel($value,'project_task', $label, $scandir); +} else if ($action == 'del') { diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 94f6137c49b..d7c332aba16 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -36,6 +36,8 @@ class Task extends CommonObject var $id; + var $ref; + var $fk_project; var $fk_task_parent; var $label; @@ -52,6 +54,7 @@ class Task extends CommonObject var $statut; var $note_private; var $note_public; + var $rang; var $timespent_id; var $timespent_duration; @@ -95,6 +98,7 @@ class Task extends CommonObject // Insert request $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task ("; $sql.= "fk_projet"; + $sql.= ", ref"; $sql.= ", fk_task_parent"; $sql.= ", label"; $sql.= ", description"; @@ -106,6 +110,7 @@ class Task extends CommonObject $sql.= ", progress"; $sql.= ") VALUES ("; $sql.= $this->fk_project; + $sql.= ", ".(!empty($this->ref)?"'".$this->db->escape($this->ref)."'":'null'); $sql.= ", ".$this->fk_task_parent; $sql.= ", '".$this->db->escape($this->label)."'"; $sql.= ", '".$this->db->escape($this->description)."'"; @@ -173,14 +178,16 @@ class Task extends CommonObject * Load object in memory from database * * @param int $id Id object + * @param int $ref ref object * @return int <0 if KO, >0 if OK */ - function fetch($id) + function fetch($id,$ref='') { global $langs; $sql = "SELECT"; $sql.= " t.rowid,"; + $sql.= " t.ref,"; $sql.= " t.fk_projet,"; $sql.= " t.fk_task_parent,"; $sql.= " t.label,"; @@ -196,9 +203,15 @@ class Task extends CommonObject $sql.= " t.progress,"; $sql.= " t.priority,"; $sql.= " t.note_private,"; - $sql.= " t.note_public"; + $sql.= " t.note_public,"; + $sql.= " t.rang"; $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as t"; - $sql.= " WHERE t.rowid = ".$id; + $sql.= " WHERE "; + if (!empty($ref)) { + $sql.="t.ref = '".$ref."'"; + }else { + $sql.="t.rowid = ".$id; + } dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); @@ -209,7 +222,7 @@ class Task extends CommonObject $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; - $this->ref = $obj->rowid; + $this->ref = $obj->ref; $this->fk_project = $obj->fk_projet; $this->fk_task_parent = $obj->fk_task_parent; $this->label = $obj->label; @@ -226,6 +239,7 @@ class Task extends CommonObject $this->priority = $obj->priority; $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; + $this->rang = $obj->rang; } $this->db->free($resql); @@ -255,6 +269,7 @@ class Task extends CommonObject // Clean parameters if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); + if (isset($this->ref)) $this->ref=trim($this->ref); if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent); if (isset($this->label)) $this->label=trim($this->label); if (isset($this->description)) $this->description=trim($this->description); @@ -267,6 +282,7 @@ class Task extends CommonObject // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET"; $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; + $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"'".$this->id."'").","; $sql.= " fk_task_parent=".(isset($this->fk_task_parent)?$this->fk_task_parent:"null").","; $sql.= " label=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").","; $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").","; @@ -274,7 +290,8 @@ class Task extends CommonObject $sql.= " planned_workload=".(isset($this->planned_workload)?$this->planned_workload:"0").","; $sql.= " dateo=".($this->date_start!=''?$this->db->idate($this->date_start):'null').","; $sql.= " datee=".($this->date_end!=''?$this->db->idate($this->date_end):'null').","; - $sql.= " progress=".$this->progress; + $sql.= " progress=".$this->progress.","; + $sql.= " rang=".((!empty($this->rang))?$this->rang:"0"); $sql.= " WHERE rowid=".$this->id; $this->db->begin(); @@ -500,6 +517,7 @@ class Task extends CommonObject $this->id=0; $this->fk_projet=''; + $this->ref=''; $this->fk_task_parent=''; $this->title=''; $this->duration_effective=''; @@ -531,7 +549,7 @@ class Task extends CommonObject // List of tasks (does not care about permissions. Filtering will be done later) $sql = "SELECT p.rowid as projectid, p.ref, p.title as plabel, p.public,"; $sql.= " t.rowid as taskid, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress,"; - $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload"; + $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.ref as ref_task,t.rang"; if ($mode == 0) { $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; @@ -583,9 +601,9 @@ class Task extends CommonObject if (! $error) { - $tasks[$i] = new stdClass(); + $tasks[$i] = new Task($db); $tasks[$i]->id = $obj->taskid; - $tasks[$i]->ref = $obj->taskid; + $tasks[$i]->ref = $obj->ref_task; $tasks[$i]->fk_project = $obj->projectid; $tasks[$i]->projectref = $obj->ref; $tasks[$i]->projectlabel = $obj->plabel; @@ -598,6 +616,7 @@ class Task extends CommonObject $tasks[$i]->public = $obj->public; $tasks[$i]->date_start = $this->db->jdate($obj->date_start); $tasks[$i]->date_end = $this->db->jdate($obj->date_end); + $tasks[$i]->rang = $obj->rang; } $i++; @@ -993,19 +1012,32 @@ class Task extends CommonObject $datec = $now; $clone_task=new Task($this->db); + $origin_task=new Task($this->db); $this->db->begin(); // Load source object $clone_task->fetch($fromid); + $origin_task->fetch($fromid); + + $defaultref=''; + $obj = empty($conf->global->PROJECT_TASK_ADDON)?'mod_task_simple':$conf->global->PROJECT_TASK_ADDON; + if (! empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) + { + require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php'; + $modTask = new $obj; + $defaultref = $modTask->getNextValue(0,$clone_task); + } $ori_project_id = $clone_task->fk_project; $clone_task->id = 0; + $clone_task->ref = $defaultref; $clone_task->fk_project = $project_id; $clone_task->fk_task_parent = $parent_task_id; $clone_task->date_c = $datec; $clone_task->planned_workload = $clone_task->planned_workload; + $clone_task->rang = $origin_task->rang; //Manage Task Date if ($clone_change_dt) diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 152c604048e..fc29a748dbe 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -114,6 +114,7 @@ if ($action == 'createtask' && $user->rights->projet->creer) $task = new Task($db); $task->fk_project = $projectid; + $task->ref = GETPOST('ref','alpha'); $task->label = $label; $task->description = $description; $task->planned_workload = $planned_workload * 3600;//We set the planned workload into seconds @@ -170,6 +171,7 @@ if ($action == 'createtask' && $user->rights->projet->creer) $form=new Form($db); $formother=new FormOther($db); +$taskstatic = new Task($db); $userstatic=new User($db); $help_url="EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; @@ -266,11 +268,27 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->socie print ''; print ''; print ''; + if (! empty($object->id)) print ''; if (! empty($mode)) print ''; print ''; + $defaultref=''; + $obj = empty($conf->global->PROJECT_TASK_ADDON)?'mod_task_simple':$conf->global->PROJECT_TASK_ADDON; + if (! empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) + { + require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php'; + $modTask = new $obj; + $defaultref = $modTask->getNextValue($soc,$object); + } + + if (is_numeric($defaultref) && $defaultref <= 0) $defaultref=''; + + // Ref + print ''; + print ''; + print ''; @@ -394,7 +412,7 @@ else print '
'.$langs->trans("Ref").''.($_POST["ref"]?$_POST["ref"]:$defaultref).'
'.$langs->trans("Label").''; print ''; print '
'; print ''; // print ''; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index bb5995ce67c..f95d93d98be 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -23,6 +23,10 @@ * \brief Page of a project task */ +error_reporting(E_ALL); +ini_set('display_errors', true); +ini_set('html_errors', false); + require ("../../main.inc.php"); require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; @@ -30,6 +34,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php'; $langs->load("projects"); $langs->load("companies"); @@ -41,8 +47,6 @@ $confirm=GETPOST('confirm','alpha'); $withproject=GETPOST('withproject','int'); $project_ref=GETPOST('project_ref','alpha'); $planned_workload=GETPOST('planned_workloadhour'); -$taskid = GETPOST("id",'int'); -$taskref = GETPOST("ref",'int'); // Security check $socid=0; @@ -73,7 +77,7 @@ if ($action == 'update' && ! $_POST["cancel"] && $user->rights->projet->creer) } if (! $error) { - $object->fetch($id); + $object->fetch($id,$ref); $tmparray=explode('_',$_POST['task_parent']); $task_parent=$tmparray[1]; @@ -100,7 +104,7 @@ if ($action == 'update' && ! $_POST["cancel"] && $user->rights->projet->creer) if ($action == 'confirm_delete' && $confirm == "yes" && $user->rights->projet->supprimer) { - if ($object->fetch($id) >= 0 ) + if ($object->fetch($id,$ref) >= 0 ) { $result=$projectstatic->fetch($object->fk_projet); if (! empty($projectstatic->socid)) @@ -142,7 +146,7 @@ if (! empty($project_ref) && ! empty($withproject)) // Build doc if ($action == 'builddoc' && $user->rights->projet->creer) { - if ($object->fetch($id) >= 0 ) + if ($object->fetch($id,$ref) >= 0 ) { if (GETPOST('model')) { @@ -174,7 +178,7 @@ if ($action == 'remove_file' && $user->rights->projet->creer) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - if ($object->fetch($id) >= 0 ) + if ($object->fetch($id,$ref) >= 0 ) { $langs->load("other"); $upload_dir = $conf->projet->dir_output; @@ -199,7 +203,7 @@ $formfile = new FormFile($db); if ($id > 0 || ! empty($ref)) { - if ($object->fetch($id) > 0) + if ($object->fetch($id,$ref) > 0) { $res=$object->fetch_optionals($object->id,$extralabels); @@ -397,7 +401,7 @@ if ($id > 0 || ! empty($ref)) $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; } else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; - print $form->showrefnav($object,'id',$linkback,1,'rowid','ref','',$param); + print $form->showrefnav($object,'ref',$linkback,1,'ref','ref','',$param); print ''; print ''; @@ -502,6 +506,7 @@ if ($id > 0 || ! empty($ref)) $var=true; $somethingshown=$formfile->show_documents('project_task',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf); + print '
'.$langs->trans("Project").''.$langs->trans("RefTask").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").'
'; From 2c8c3857ba1fc494b47f8fed04f9f0b07dcbeb18 Mon Sep 17 00:00:00 2001 From: Florian Henry Date: Thu, 18 Jul 2013 10:25:50 +0200 Subject: [PATCH 4/4] Update change Log --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 55249d9fb82..028cc1c85e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,9 @@ For users: - New: Add option MAIN_GENERATE_DOCUMENT_WITH_PICTURE. - New: Add option excludethirdparties and onlythirdparties into merge pdf scripts. - Qual: Implement same rule for return value of all command line scripts (0 when success, <>0 if error). +- New : [ task #925 ] Add ODT document generation for Tasks in project module +- New : [ task #924 ] Add numbering rule on task + For translators: - Normalized sort order of all languages files with english reference files.