PageRenderTime 128ms CodeModel.GetById 60ms app.highlight 25ms RepoModel.GetById 36ms app.codeStats 0ms

/htdocs/facture/core/modules/facture/doc/doc_generic_invoice_odt.modules.php

https://bitbucket.org/speedealing/speedealing
PHP | 519 lines | 364 code | 56 blank | 99 comment | 35 complexity | 822aa3b1da22fd782685da50ac34e81a MD5 | raw file
  1<?php
  2/* Copyright (C) 2010-2012	Laurent Destailleur	<ely@users.sourceforge.net>
  3 * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
  4
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License as published by
  7 * the Free Software Foundation; either version 3 of the License, or
  8 * (at your option) any later version.
  9 *
 10 * This program is distributed in the hope that it will be useful,
 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13 * GNU General Public License for more details.
 14 *
 15 * You should have received a copy of the GNU General Public License
 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 17 * or see http://www.gnu.org/
 18 */
 19
 20/**
 21 *	\file       htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
 22 *	\ingroup    societe
 23 *	\brief      File of class to build ODT documents for third parties
 24 */
 25
 26require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
 27require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
 28require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
 29require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 30require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 31require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
 32
 33
 34/**
 35 *	Class to build documents using ODF templates generator
 36 */
 37class doc_generic_invoice_odt extends ModelePDFFactures
 38{
 39	var $emetteur;	// Objet societe qui emet
 40
 41	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
 42	var $version = 'dolibarr';
 43
 44
 45	/**
 46	 *	Constructor
 47	 *
 48	 *  @param		DoliDB		$db      Database handler
 49	 */
 50	function __construct($db = '')
 51	{
 52		global $conf,$langs,$mysoc;
 53
 54		$langs->load("main");
 55		$langs->load("companies");
 56
 57		$this->db = $db;
 58		$this->name = "ODT templates";
 59		$this->description = $langs->trans("DocumentModelOdt");
 60		$this->scandir = 'FACTURE_ADDON_PDF_ODT_PATH';	// Name of constant that is used to save list of directories to scan
 61
 62		// Dimension page pour format A4
 63		$this->type = 'odt';
 64		$this->page_largeur = 0;
 65		$this->page_hauteur = 0;
 66		$this->format = array($this->page_largeur,$this->page_hauteur);
 67		$this->marge_gauche=0;
 68		$this->marge_droite=0;
 69		$this->marge_haute=0;
 70		$this->marge_basse=0;
 71
 72		$this->option_logo = 1;                    // Affiche logo
 73		$this->option_tva = 0;                     // Gere option tva FACTURE_TVAOPTION
 74		$this->option_modereg = 0;                 // Affiche mode reglement
 75		$this->option_condreg = 0;                 // Affiche conditions reglement
 76		$this->option_codeproduitservice = 0;      // Affiche code produit-service
 77		$this->option_multilang = 0;               // Dispo en plusieurs langues
 78		$this->option_escompte = 0;                // Affiche si il y a eu escompte
 79		$this->option_credit_note = 0;             // Support credit notes
 80		$this->option_freetext = 1;				   // Support add of a personalised text
 81		$this->option_draft_watermark = 0;		   // Support add of a watermark on drafts
 82
 83		// Recupere emetteur
 84		$this->emetteur=$mysoc;
 85		if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2);    // Par defaut, si n'etait pas defini
 86	}
 87
 88
 89    /**
 90     * Define array with couple substitution key => substitution value
 91     *
 92     * @param   Object			$object             Main object to use as data source
 93     * @param   Translate		$outputlangs        Lang object to use for output
 94     * @return	array								Array of substitution
 95     */
 96    function get_substitutionarray_object($object,$outputlangs)
 97    {
 98        global $conf;
 99
100        $invoice_source=new Facture($this->db);
101		if ($object->fk_facture_source > 0)
102		{
103        	$invoice_source->fetch($object->fk_facture_source);
104		}
105		$sumpayed = $object->getSommePaiement();
106		$alreadypayed=price($sumpayed,0,$outputlangs);
107
108        return array(
109            'object_id'=>$object->id,
110            'object_ref'=>$object->ref,
111            'object_ref_ext'=>$object->ref_ext,
112        	'object_ref_customer'=>$object->ref_client,
113            'object_ref_supplier'=>(! empty($object->ref_fournisseur)?$object->ref_fournisseur:''),
114            'object_source_invoice_ref'=>$invoice_source->ref,
115        	'object_date'=>dol_print_date($object->date,'day'),
116        	'object_date_limit'=>dol_print_date($object->date_lim_reglement,'day'),
117        	'object_date_creation'=>dol_print_date($object->date_creation,'day'),
118            'object_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''),
119            'object_date_validation'=>dol_print_date($object->date_validation,'dayhour'),
120            'object_payment_mode_code'=>$object->mode_reglement_code,
121        	'object_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement),
122        	'object_payment_term_code'=>$object->cond_reglement_code,
123        	'object_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):$object->cond_reglement),
124        	'object_total_ht'=>price($object->total_ht,0,$outputlangs),
125            'object_total_vat'=>price($object->total_tva,0,$outputlangs),
126            'object_total_ttc'=>price($object->total_ttc,0,$outputlangs),
127            'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs),
128            'object_vatrate'=>(isset($object->tva)?vatrate($object->tva):''),
129            'object_note_private'=>$object->note,
130            'object_note'=>$object->note_public,
131        	// Payments
132            'object_already_payed'=>$alreadypayed,
133            'object_remain_to_pay'=>price($object->total_ttc - $sumpayed,0,$outputlangs)
134        );
135    }
136
137    /**
138     * Define array with couple substitution key => substitution value
139     *
140     * @param   array		$line			Array of lines
141     * @param   Translate	$outputlangs    Lang object to use for output
142     * @return	array						Return substitution array
143     */
144    function get_substitutionarray_lines($line,$outputlangs)
145    {
146        global $conf;
147
148        return array(
149            'line_fulldesc'=>doc_getlinedesc($line,$outputlangs),
150            'line_product_ref'=>$line->product_ref,
151            'line_product_label'=>$line->product_label,
152        	'line_desc'=>$line->desc,
153            'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits),
154            'line_up'=>price($line->subprice, 0, $outputlangs),
155            'line_qty'=>$line->qty,
156            'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''),
157            'line_price_ht'=>price($line->total_ht, 0, $outputlangs),
158            'line_price_ttc'=>price($line->total_ttc, 0, $outputlangs),
159            'line_price_vat'=>price($line->total_tva, 0, $outputlangs),
160            'line_date_start'=>$line->date_start,
161            'line_date_end'=>$line->date_end
162        );
163    }
164
165	/**
166	 * Return description of a module
167	 *
168     * @param	Translate	$langs      Lang object to use for output
169	 * @return	string      			Description
170	 */
171	function info($langs)
172	{
173		global $conf,$langs;
174
175		$langs->load("companies");
176		$langs->load("errors");
177
178		$form = new Form($this->db);
179
180		$texte = $this->description.".<br>\n";
181		$texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
182		$texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
183		$texte.= '<input type="hidden" name="action" value="setModuleOptions">';
184		$texte.= '<input type="hidden" name="param1" value="FACTURE_ADDON_PDF_ODT_PATH">';
185		$texte.= '<table class="nobordernopadding" width="100%">';
186
187		// List of directories area
188		$texte.= '<tr><td>';
189		$texttitle=$langs->trans("ListOfDirectories");
190		$listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->FACTURE_ADDON_PDF_ODT_PATH)));
191		$listoffiles=array();
192		foreach($listofdir as $key=>$tmpdir)
193		{
194			$tmpdir=trim($tmpdir);
195			$tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir);
196			if (! $tmpdir) { unset($listofdir[$key]); continue; }
197			if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0);
198			else
199			{
200				$tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt');
201				if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
202			}
203		}
204		$texthelp=$langs->trans("ListOfDirectoriesForModelGenODT");
205		// Add list of substitution keys
206		$texthelp.='<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
207 		$texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation");    // This contains an url, we don't modify it
208
209		$texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1);
210		$texte.= '<table><tr><td>';
211		$texte.= '<textarea class="flat" cols="60" name="value1">';
212		$texte.=$conf->global->FACTURE_ADDON_PDF_ODT_PATH;
213		$texte.= '</textarea>';
214        $texte.= '</td>';
215		$texte.= '<td align="center">&nbsp; ';
216        $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">';
217        $texte.= '</td>';
218		$texte.= '</tr>';
219        $texte.= '</table>';
220
221		// Scan directories
222		if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': <b>'.count($listoffiles).'</b>';
223
224		$texte.= '</td>';
225
226
227		$texte.= '<td valign="top" rowspan="2">';
228		$texte.= $langs->trans("ExampleOfDirectoriesForModelGen");
229		$texte.= '</td>';
230		$texte.= '</tr>';
231
232		/*$texte.= '<tr>';
233		$texte.= '<td align="center">';
234		$texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">';
235		$texte.= '</td>';
236		$texte.= '</tr>';*/
237
238		$texte.= '</table>';
239		$texte.= '</form>';
240
241		return $texte;
242	}
243
244	/**
245	 *	Function to build a document on disk using the generic odt module.
246	 *
247	 *	@param	Facture		$object					Object source to build document
248	 *	@param	Translate	$outputlangs			Lang output object
249	 * 	@param	string		$srctemplatepath	    Full path of source filename for generator using a template file
250	 *	@return	int         						1 if OK, <=0 if KO
251	 */
252	function write_file($object,$outputlangs,$srctemplatepath)
253	{
254		global $user,$langs,$conf,$mysoc;
255
256		if (empty($srctemplatepath))
257		{
258			dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
259			return -1;
260		}
261
262		if (! is_object($outputlangs)) $outputlangs=$langs;
263		$sav_charset_output=$outputlangs->charset_output;
264		$outputlangs->charset_output='UTF-8';
265
266		$outputlangs->load("main");
267		$outputlangs->load("dict");
268		$outputlangs->load("companies");
269		$outputlangs->load("bills");
270
271		if ($conf->facture->dir_output)
272		{
273			// If $object is id instead of object
274			if (! is_object($object))
275			{
276				$id = $object;
277				$object = new Facture($this->db);
278				$result=$object->fetch($id);
279				if ($result < 0)
280				{
281					dol_print_error($this->db,$object->error);
282					return -1;
283				}
284			}
285
286			$dir = $conf->facture->dir_output;
287			$objectref = dol_sanitizeFileName($object->ref);
288			if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref;
289			$file = $dir . "/" . $objectref . ".odt";
290
291			if (! file_exists($dir))
292			{
293				if (dol_mkdir($dir) < 0)
294				{
295					$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
296					return -1;
297				}
298			}
299
300			if (file_exists($dir))
301			{
302				//print "srctemplatepath=".$srctemplatepath;exit;	// Src filename
303				$newfile=basename($srctemplatepath);
304				$newfiletmp=preg_replace('/\.odt/i','',$newfile);
305				$newfiletmp=preg_replace('/template_/i','',$newfiletmp);
306				$newfiletmp=preg_replace('/modele_/i','',$newfiletmp);
307			    $newfiletmp=$objectref.'_'.$newfiletmp;
308				//$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
309				$file=$dir.'/'.$newfiletmp.'.odt';
310				//print "newdir=".$dir;
311				//print "newfile=".$newfile;
312				//print "file=".$file;
313				//print "conf->societe->dir_temp=".$conf->societe->dir_temp;
314
315				dol_mkdir($conf->facture->dir_temp);
316
317
318                // If BILLING contact defined on invoice, we use it
319                $usecontact=false;
320                $arrayidcontact=$object->getIdContact('external','BILLING');
321                if (count($arrayidcontact) > 0)
322                {
323                    $usecontact=true;
324                    $result=$object->fetch_contact($arrayidcontact[0]);
325                }
326
327                // Recipient name
328                if (! empty($usecontact))
329                {
330                    // On peut utiliser le nom de la societe du contact
331                    if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact;
332                    else $socobject = $object->client;
333                }
334                else
335                {
336                    $socobject=$object->client;
337                }
338
339                // Make substitution
340                $substitutionarray=array(
341                    '__FROM_NAME__' => $this->emetteur->nom,
342                    '__FROM_EMAIL__' => $this->emetteur->email,
343                    '__TOTAL_TTC__' => $object->total_ttc,
344                    '__TOTAL_HT__' => $object->total_ht,
345                    '__TOTAL_VAT__' => $object->total_tva
346                );
347                complete_substitutions_array($substitutionarray, $langs, $object);
348
349				// Line of free text
350				$newfreetext='';
351				$paramfreetext='FACTURE_FREE_TEXT';
352			    if (! empty($conf->global->$paramfreetext))
353			    {
354			        $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray);
355			    }
356
357                // Open and load template
358				require_once ODTPHP_PATH.'odf.php';
359				$odfHandler = new odf(
360				    $srctemplatepath,
361				    array(
362						'PATH_TO_TMP'	  => $conf->facture->dir_temp,
363						'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
364						'DELIMITER_LEFT'  => '{',
365						'DELIMITER_RIGHT' => '}'
366					)
367				);
368				// After construction $odfHandler->contentXml contains content and
369				// [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
370				// [!-- BEGIN lines --]*[!-- END lines --]
371                //print html_entity_decode($odfHandler->__toString());
372                //print exit;
373
374
375				// Make substitutions into odt of freetext
376				try {
377					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
378				}
379				catch(OdfException $e)
380				{
381				}
382
383                // Make substitutions into odt of user info
384				$tmparray=$this->get_substitutionarray_user($user,$outputlangs);
385                //var_dump($tmparray); exit;
386                foreach($tmparray as $key=>$value)
387                {
388                    try {
389                        if (preg_match('/logo$/',$key)) // Image
390                        {
391                            //var_dump($value);exit;
392                            if (file_exists($value)) $odfHandler->setImage($key, $value);
393                            else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
394                        }
395                        else    // Text
396                        {
397                            $odfHandler->setVars($key, $value, true, 'UTF-8');
398                        }
399                    }
400                    catch(OdfException $e)
401                    {
402                    }
403                }
404                // Make substitutions into odt of mysoc
405                $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs);
406				//var_dump($tmparray); exit;
407				foreach($tmparray as $key=>$value)
408				{
409					try {
410						if (preg_match('/logo$/',$key))	// Image
411						{
412							//var_dump($value);exit;
413							if (file_exists($value)) $odfHandler->setImage($key, $value);
414							else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
415						}
416						else	// Text
417						{
418							$odfHandler->setVars($key, $value, true, 'UTF-8');
419						}
420					}
421					catch(OdfException $e)
422					{
423					}
424				}
425                // Make substitutions into odt of thirdparty
426				$tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs);
427				foreach($tmparray as $key=>$value)
428				{
429					try {
430						if (preg_match('/logo$/',$key))	// Image
431						{
432							if (file_exists($value)) $odfHandler->setImage($key, $value);
433							else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
434						}
435						else	// Text
436						{
437							$odfHandler->setVars($key, $value, true, 'UTF-8');
438						}
439					}
440					catch(OdfException $e)
441					{
442					}
443				}
444				// Replace tags of object + external modules
445			    $tmparray=$this->get_substitutionarray_object($object,$outputlangs);
446			    complete_substitutions_array($tmparray, $outputlangs, $object);
447                foreach($tmparray as $key=>$value)
448                {
449                    try {
450                        if (preg_match('/logo$/',$key)) // Image
451                        {
452                            if (file_exists($value)) $odfHandler->setImage($key, $value);
453                            else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
454                        }
455                        else    // Text
456                        {
457                            $odfHandler->setVars($key, $value, true, 'UTF-8');
458                        }
459                    }
460                    catch(OdfException $e)
461                    {
462                    }
463                }
464				// Replace tags of lines
465                try
466                {
467                    $listlines = $odfHandler->setSegment('lines');
468                    foreach ($object->lines as $line)
469                    {
470                        $tmparray=$this->get_substitutionarray_lines($line,$outputlangs);
471                        complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
472                        foreach($tmparray as $key => $val)
473                        {
474                             try
475                             {
476                                $listlines->setVars($key, $val, true, 'UTF-8');
477                             }
478                             catch(OdfException $e)
479                             {
480                             }
481                             catch(SegmentException $e)
482                             {
483                             }
484                        }
485                        $listlines->merge();
486                    }
487                    $odfHandler->mergeSegment($listlines);
488                }
489                catch(OdfException $e)
490                {
491                    $this->error=$e->getMessage();
492                    dol_syslog($this->error, LOG_WARNING);
493                    return -1;
494                }
495
496                // Write new file
497				//$result=$odfHandler->exportAsAttachedFile('toto');
498				$odfHandler->saveToDisk($file);
499
500				if (! empty($conf->global->MAIN_UMASK))
501				@chmod($file, octdec($conf->global->MAIN_UMASK));
502
503				$odfHandler=null;	// Destroy object
504
505				return 1;   // Success
506			}
507			else
508			{
509				$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
510				return -1;
511			}
512		}
513
514		return -1;
515	}
516
517}
518
519?>