From 2a61569d9a4998da35fa68176c3c70a2a4c5cc58 Mon Sep 17 00:00:00 2001 From: simnandez Date: Mon, 2 Jan 2012 18:23:41 +0100 Subject: [PATCH 1/2] [ task #176 ] Allow to use ODT templates for prososal like it's done for invoices. Firsts works --- htdocs/admin/propale.php | 201 +++---- htdocs/core/modules/modPropale.class.php | 13 + .../doc_generic_proposal_odt.modules.php | 495 ++++++++++++++++++ .../proposals/template_proposal.odt | Bin 0 -> 25191 bytes 4 files changed, 618 insertions(+), 91 deletions(-) create mode 100644 htdocs/core/modules/propale/doc_generic_proposal_odt.modules.php create mode 100644 htdocs/install/doctemplates/proposals/template_proposal.odt diff --git a/htdocs/admin/propale.php b/htdocs/admin/propale.php index 014dd09983097..fd80e75f8b439 100644 --- a/htdocs/admin/propale.php +++ b/htdocs/admin/propale.php @@ -6,7 +6,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) - * Copyright (C) 2011 Juanjo Menent + * Copyright (C) 2011-2012 Juanjo Menent * * 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 @@ -405,102 +405,121 @@ clearstatcache(); +$var=true; foreach ($conf->file->dol_document_root as $dirroot) { - $dir = $dirroot . "/core/modules/propale/"; - - if (is_dir($dir)) - { - $var=true; - - $handle=opendir($dir); - if (is_resource($handle)) - { - while (($file = readdir($handle))!==false) - { - if (substr($file, dol_strlen($file) -12) == '.modules.php' && substr($file,0,12) == 'pdf_propale_') - { - $name = substr($file, 12, dol_strlen($file) - 24); - $classname = substr($file, 0, dol_strlen($file) -12); - - $var=!$var; - print "\n "; - print $name; - print "\n \n"; - require_once($dir.$file); - $module = new $classname($db); - print $module->description; - print ''; - - // Activate - print ''."\n"; - if (in_array($name, $def)) - { - //if ($conf->global->PROPALE_ADDON_PDF != "$name") - //{ - print 'scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Activated"),'switch_on'); - print ''; - //} - //else - //{ - // print img_picto($langs->trans("Activated"),'switch_on'); - //} - } - else - { - print 'scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Disabled"),'switch_off'); - print ''; - } - print ""; - - // Default - print ''; - if ($conf->global->PROPALE_ADDON_PDF == "$name") - { - print img_picto($langs->trans("Yes"),'on'); - } - else - { - print 'scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("No"),'off'); - print ''; - } - print ''; - - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); - if ($module->type == 'pdf') + foreach (array('','/doc') as $valdir) + { + $dir = $dirroot . "/core/modules/propale".$valdir; + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) { - $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + 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 ''; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''; + } + else + { + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print ""; + } + + // Defaut + print ""; + if ($conf->global->PROPALE_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 ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $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); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); + $htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftInvoices").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + + // Preview + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'bill').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print ''; + + print "\n"; + } + } } - $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; - $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); - $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); - $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); - $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); - //$htmltooltip.='
'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); - //$htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); - $htmltooltip.='
'.$langs->trans("WatermarkOnDraftProposal").': '.yn($module->option_draft_watermark,1,1); - - print ''; - print $form->textwithpicto('',$htmltooltip,1,0); - print ''; - print ''; - print ''.img_object($langs->trans("Preview"),'propal').''; - print ''; - - print "\n"; - } - } - closedir($handle); - } - } + } + } + } + } } - print ''; print '
'; diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index 3d67b95afa7b8..a45779a4f5c46 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2012 Juanjo Menentr * * 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 @@ -94,6 +95,12 @@ function modPropale($DB) $this->const[$r][3] = 'Duration of validity of business proposals'; $this->const[$r][4] = 0; $r++; + + $this->const[$r][0] = "PROPALE_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/proposals"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; // Boxes $this->boxes = array(); @@ -183,6 +190,12 @@ function init() // Remove permissions and default values $this->remove(); + + //ODT template + require_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'); + $dirodt=DOL_DATA_ROOT.'/doctemplates/proposals'; + create_exdir($dirodt); + dol_copy(DOL_DOCUMENT_ROOT.'/install/doctemplates/proposals/template_proposal.odt',$dirodt.'/template_proposal.odt',0,0); $sql = array( "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->const[0][2]."' AND entity = ".$conf->entity, diff --git a/htdocs/core/modules/propale/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc_generic_proposal_odt.modules.php new file mode 100644 index 0000000000000..63a0cef81c528 --- /dev/null +++ b/htdocs/core/modules/propale/doc_generic_proposal_odt.modules.php @@ -0,0 +1,495 @@ + + * Copyright (C) 2012 Juanjo Menent + * + * 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, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/propale/doc_generic_proposal_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once(DOL_DOCUMENT_ROOT."/core/modules/propale/modules_propale.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); + + +/** + * \class doc_generic_iproposal_odt + * \brief Class to build documents using ODF templates generator + */ +class doc_generic_proposal_odt extends ModelePDFPropales +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'development'; + + + /** + * Constructor + * + * @param DoliDB $DB Database handler + */ + function doc_generic_proposal_odt($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 = 'PROPALE_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 PROPALE_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 + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; + + return array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_ref_ext'=>$object->ref_ext, + 'object_ref_customer'=>$object->ref_client, + 'object_date'=>dol_print_date($object->date,'day'), + 'object_fin_validite'=>dol_print_date($object->fin_validite,'dayhour'), + 'object_date_creation'=>dol_print_date($object->date_creation,'day'), + 'object_date_modification'=>dol_print_date($object->date_modification,'day'), + 'object_date_validation'=>dol_print_date($object->date_validation,'dayhour'), + 'object_payment_mode'=>$object->mode_reglement, + 'object_payment_term'=>$object->cond_reglement, + 'object_total_ht'=>price($object->total_ht,0,$outputlangs), + 'object_total_vat'=>price($object->total_tva,0,$outputlangs), + 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), + 'object_vatrate'=>vatrate($object->tva), + 'object_note_private'=>$object->note, + 'object_note'=>$object->note_public, + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $line + * @param Translate $outputlangs Lang object to use for output + */ + function get_substitutionarray_lines($line,$outputlangs) + { + global $conf; + + return array( + 'line_fulldesc'=>$line->product_ref.(($line->product_ref && $line->desc)?' - ':'').$line->desc, + 'line_product_ref'=>$line->product_ref, + 'line_desc'=>$line->desc, + 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), + 'line_up'=>price($line->subprice, 0, $outputlangs), + 'line_qty'=>$line->qty, + 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), + 'line_price_ht'=>price($line->total_ht, 0, $outputlangs), + 'line_price_ttc'=>price($line->total_ttc, 0, $outputlangs), + 'line_price_vat'=>price($line->total_tva, 0, $outputlangs), + 'line_date_start'=>$line->date_start, + 'line_date_end'=>$line->date_end + ); + } + + /** + * Return description of a module + * @param 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->PROPALE_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 Propale $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("bills"); + + if ($conf->propale->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Propale($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->propale->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (create_exdir($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; + + create_exdir($conf->propale->dir_temp); + + + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if ($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) $socobject = $object->contact; + else $socobject = $object->client; + } + else + { + $socobject=$object->client; + } + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + + // Line of free text + $newfreetext=''; + $paramfreetext='PROPALE_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once(ODTPHP_PATH.'odf.php'); + $odfHandler = new odf($srctemplatepath, array( + 'PATH_TO_TMP' => $conf->propale->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 freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // 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'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_object($object,$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 + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line,$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 + //$result=$odfHandler->exportAsAttachedFile('toto'); + $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; + } + +} + +?> diff --git a/htdocs/install/doctemplates/proposals/template_proposal.odt b/htdocs/install/doctemplates/proposals/template_proposal.odt new file mode 100644 index 0000000000000000000000000000000000000000..0fda0975446d8ce08441c91d2e725e7c4b58fc67 GIT binary patch literal 25191 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 Io#(y(1DKulO#lD@ literal 0 HcmV?d00001 From e7c44447d0c91a3688b959c20cb883f7db323f89 Mon Sep 17 00:00:00 2001 From: simnandez Date: Mon, 2 Jan 2012 18:31:01 +0100 Subject: [PATCH 2/2] [ task #176 ] Allow to use ODT templates for prososal like it's done for invoices. Firsts works --- htdocs/admin/propale.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/admin/propale.php b/htdocs/admin/propale.php index fd80e75f8b439..b9e5bf5af3024 100644 --- a/htdocs/admin/propale.php +++ b/htdocs/admin/propale.php @@ -484,14 +484,14 @@ { $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); - $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); - $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); - $htmltooltip.='
'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); - $htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); - $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); - $htmltooltip.='
'.$langs->trans("WatermarkOnDraftInvoices").': '.yn($module->option_draft_watermark,1,1); + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + //$htmltooltip.='
'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); + //$htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftProposal").': '.yn($module->option_draft_watermark,1,1); print '';