dolibarr  13.0.2
printsheet.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4  * Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must ne renew the token.
27  if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
28 }
29 
30 require '../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/modules/printsheet/modules_labels.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
35 
36 // Load translation files required by the page
37 $langs->loadLangs(array('admin', 'members', 'errors'));
38 
39 // Choice of print year or current year.
40 $now = dol_now();
41 $year = dol_print_date($now, '%Y');
42 $month = dol_print_date($now, '%m');
43 $day = dol_print_date($now, '%d');
44 $forbarcode = GETPOST('forbarcode', 'alphanohtml');
45 $fk_barcode_type = GETPOST('fk_barcode_type', 'int');
46 $mode = GETPOST('mode', 'aZ09');
47 $modellabel = GETPOST("modellabel", 'aZ09'); // Doc template to use
48 $numberofsticker = GETPOST('numberofsticker', 'int');
49 
50 $mesg = '';
51 
52 $action = GETPOST('action', 'aZ09');
53 
54 $producttmp = new Product($db);
55 $thirdpartytmp = new Societe($db);
56 
57 
58 /*
59  * Actions
60  */
61 
62 if (GETPOST('submitproduct') && GETPOST('submitproduct'))
63 {
64  $action = ''; // We reset because we don't want to build doc
65  if (GETPOST('productid', 'int') > 0) {
66  $result = $producttmp->fetch(GETPOST('productid', 'int'));
67  if ($result < 0) {
68  setEventMessage($producttmp->error, 'errors');
69  }
70  $forbarcode = $producttmp->barcode;
71  $fk_barcode_type = $producttmp->barcode_type;
72 
73  if (empty($fk_barcode_type) && !empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
74 
75  if (empty($forbarcode) || empty($fk_barcode_type))
76  {
77  setEventMessages($langs->trans("DefinitionOfBarCodeForProductNotComplete", $producttmp->getNomUrl()), null, 'warnings');
78  }
79  }
80 }
81 if (GETPOST('submitthirdparty') && GETPOST('submitthirdparty'))
82 {
83  $action = ''; // We reset because we don't want to build doc
84  if (GETPOST('socid', 'int') > 0)
85  {
86  $thirdpartytmp->fetch(GETPOST('socid', 'int'));
87  $forbarcode = $thirdpartytmp->barcode;
88  $fk_barcode_type = $thirdpartytmp->barcode_type_code;
89 
90  if (empty($fk_barcode_type) && !empty($conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY)) $fk_barcode_type = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY;
91 
92  if (empty($forbarcode) || empty($fk_barcode_type))
93  {
94  setEventMessages($langs->trans("DefinitionOfBarCodeForThirdpartyNotComplete", $thirdpartytmp->getNomUrl()), null, 'warnings');
95  }
96  }
97 }
98 
99 if ($action == 'builddoc')
100 {
101  $result = 0; $error = 0;
102 
103  if (empty($forbarcode)) // barcode value
104  {
105  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BarcodeValue")), null, 'errors');
106  $error++;
107  }
108  if (empty($fk_barcode_type)) // barcode type = barcode encoding
109  {
110  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BarcodeType")), null, 'errors');
111  $error++;
112  }
113 
114  if (!$error)
115  {
116  // Get encoder (barcode_type_coder) from barcode type id (barcode_type)
117  $stdobject = new GenericObject($db);
118  $stdobject->barcode_type = $fk_barcode_type;
119  $result = $stdobject->fetch_barcode();
120  if ($result <= 0)
121  {
122  $error++;
123  setEventMessages('Failed to get bar code type information '.$stdobject->error, $stdobject->errors, 'errors');
124  }
125  }
126 
127  if (!$error)
128  {
129  $code = $forbarcode;
130  $generator = $stdobject->barcode_type_coder; // coder (loaded by fetch_barcode). Engine.
131  $encoding = strtoupper($stdobject->barcode_type_code); // code (loaded by fetch_barcode). Example 'ean', 'isbn', ...
132 
133  $diroutput = $conf->barcode->dir_temp;
134  dol_mkdir($diroutput);
135 
136  // Generate barcode
137  $dirbarcode = array_merge(array("/core/modules/barcode/doc/"), $conf->modules_parts['barcode']);
138 
139  foreach ($dirbarcode as $reldir)
140  {
141  $dir = dol_buildpath($reldir, 0);
142  $newdir = dol_osencode($dir);
143 
144  // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
145  if (!is_dir($newdir)) continue;
146 
147  $result = @include_once $newdir.$generator.'.modules.php';
148  if ($result) break;
149  }
150 
151  // Load barcode class for generating barcode image
152  $classname = "mod".ucfirst($generator);
153  $module = new $classname($db);
154  if ($generator != 'tcpdfbarcode')
155  {
156  // May be phpbarcode
157  $template = 'standardlabel';
158  $is2d = false;
159  if ($module->encodingIsSupported($encoding))
160  {
161  $barcodeimage = $conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png';
162  dol_delete_file($barcodeimage);
163  // File is created with full name $barcodeimage = $conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png';
164  $result = $module->writeBarCode($code, $encoding, 'Y', 4, 1);
165  if ($result <= 0 || !dol_is_file($barcodeimage))
166  {
167  $error++;
168  setEventMessages('Failed to generate image file of barcode for code='.$code.' encoding='.$encoding.' file='.basename($barcodeimage), null, 'errors');
169  setEventMessages($module->error, null, 'errors');
170  }
171  } else {
172  $error++;
173  setEventMessages("Error, encoding ".$encoding." is not supported by encoder ".$generator.'. You must choose another barcode type or install a barcode generation engine that support '.$encoding, null, 'errors');
174  }
175  } else {
176  $template = 'tcpdflabel';
177  $encoding = $module->getTcpdfEncodingType($encoding); //convert to TCPDF compatible encoding types
178  $is2d = $module->is2d;
179  }
180  }
181 
182  if (!$error)
183  {
184  // List of values to scan for a replacement
185  $substitutionarray = array(
186  '%LOGIN%' => $user->login,
187  '%COMPANY%' => $mysoc->name,
188  '%ADDRESS%' => $mysoc->address,
189  '%ZIP%' => $mysoc->zip,
190  '%TOWN%' => $mysoc->town,
191  '%COUNTRY%' => $mysoc->country,
192  '%COUNTRY_CODE%' => $mysoc->country_code,
193  '%EMAIL%' => $mysoc->email,
194  '%YEAR%' => $year,
195  '%MONTH%' => $month,
196  '%DAY%' => $day,
197  '%DOL_MAIN_URL_ROOT%' => DOL_MAIN_URL_ROOT,
198  '%SERVER%' => "http://".$_SERVER["SERVER_NAME"]."/",
199  );
200  complete_substitutions_array($substitutionarray, $langs);
201 
202  // For labels
203  if ($mode == 'label')
204  {
205  $txtforsticker = "%PHOTO%"; // Photo will be barcode image, %BARCODE% posible when using TCPDF generator
206  $textleft = make_substitutions((empty($conf->global->BARCODE_LABEL_LEFT_TEXT) ? $txtforsticker : $conf->global->BARCODE_LABEL_LEFT_TEXT), $substitutionarray);
207  $textheader = make_substitutions((empty($conf->global->BARCODE_LABEL_HEADER_TEXT) ? '' : $conf->global->BARCODE_LABEL_HEADER_TEXT), $substitutionarray);
208  $textfooter = make_substitutions((empty($conf->global->BARCODE_LABEL_FOOTER_TEXT) ? '' : $conf->global->BARCODE_LABEL_FOOTER_TEXT), $substitutionarray);
209  $textright = make_substitutions((empty($conf->global->BARCODE_LABEL_RIGHT_TEXT) ? '' : $conf->global->BARCODE_LABEL_RIGHT_TEXT), $substitutionarray);
210  $forceimgscalewidth = (empty($conf->global->BARCODE_FORCEIMGSCALEWIDTH) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEWIDTH);
211  $forceimgscaleheight = (empty($conf->global->BARCODE_FORCEIMGSCALEHEIGHT) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEHEIGHT);
212 
213  for ($i = 0; $i < $numberofsticker; $i++)
214  {
215  $arrayofrecords[] = array(
216  'textleft'=>$textleft,
217  'textheader'=>$textheader,
218  'textfooter'=>$textfooter,
219  'textright'=>$textright,
220  'code'=>$code,
221  'encoding'=>$encoding,
222  'is2d'=>$is2d,
223  'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF
224  );
225  }
226  }
227 
228  $i++;
229  $mesg = '';
230 
231  // Build and output PDF
232  if ($mode == 'label')
233  {
234  if (!count($arrayofrecords))
235  {
236  $mesg = $langs->trans("ErrorRecordNotFound");
237  }
238  if (empty($modellabel) || $modellabel == '-1')
239  {
240  $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DescADHERENT_ETIQUETTE_TYPE"));
241  }
242 
243  $outfile = $langs->trans("BarCode").'_sheets_'.dol_print_date(dol_now(), 'dayhourlog').'.pdf';
244 
245  if (!$mesg) {
246  $outputlangs = $langs;
247 
248  // This generates and send PDF to output
249  // TODO Move
250  $result = doc_label_pdf_create($db, $arrayofrecords, $modellabel, $outputlangs, $diroutput, $template, dol_sanitizeFileName($outfile));
251  }
252  }
253 
254  if ($result <= 0 || $mesg) {
255  if (empty($mesg)) {
256  $mesg = 'Error '.$result;
257  }
258 
259  setEventMessages($mesg, null, 'errors');
260  } else {
261  $db->close();
262  exit;
263  }
264  }
265 }
266 
267 
268 /*
269  * View
270  */
271 
272 if (empty($conf->barcode->enabled)) accessforbidden();
273 
274 $form = new Form($db);
275 
276 llxHeader('', $langs->trans("BarCodePrintsheet"));
277 
278 print load_fiche_titre($langs->trans("BarCodePrintsheet"), '', 'barcode');
279 print '<br>';
280 
281 print '<span class="opacitymedium">'.$langs->trans("PageToGenerateBarCodeSheets", $langs->transnoentitiesnoconv("BuildPageToPrint")).'</span><br>';
282 print '<br>';
283 
284 dol_htmloutput_errors($mesg);
285 
286 //print img_picto('','puce').' '.$langs->trans("PrintsheetForOneBarCode").'<br>';
287 //print '<br>';
288 
289 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; // The target is for brothers that open the file instead of downloading it
290 print '<input type="hidden" name="mode" value="label">';
291 print '<input type="hidden" name="action" value="builddoc">';
292 print '<input type="hidden" name="token" value="'.currentToken().'">'; // The page will not renew the token but force download of a file, so we must use here currentToken
293 
294 print '<div class="tagtable">';
295 
296 // Sheet format
297 print ' <div class="tagtr">';
298 print ' <div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
299 print $langs->trans("DescADHERENT_ETIQUETTE_TYPE").' &nbsp; ';
300 print '</div><div class="tagtd maxwidthonsmartphone" style="overflow: hidden; white-space: nowrap;">';
301 // List of possible labels (defined into $_Avery_Labels variable set into core/lib/format_cards.lib.php)
302 $arrayoflabels = array();
303 foreach (array_keys($_Avery_Labels) as $codecards)
304 {
305  $labeltoshow = $_Avery_Labels[$codecards]['name'];
306  //$labeltoshow.=' ('.$_Avery_Labels[$row['code']]['paper-size'].')';
307  $arrayoflabels[$codecards] = $labeltoshow;
308 }
309 asort($arrayoflabels);
310 print $form->selectarray('modellabel', $arrayoflabels, (GETPOST('modellabel') ?GETPOST('modellabel') : $conf->global->ADHERENT_ETIQUETTE_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1);
311 print '</div></div>';
312 
313 // Number of stickers to print
314 print ' <div class="tagtr">';
315 print ' <div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
316 print $langs->trans("NumberOfStickers").' &nbsp; ';
317 print '</div><div class="tagtd maxwidthonsmartphone" style="overflow: hidden; white-space: nowrap;">';
318 print '<input size="4" type="text" name="numberofsticker" value="'.(GETPOST('numberofsticker') ?GETPOST('numberofsticker', 'int') : 10).'">';
319 print '</div></div>';
320 
321 print '</div>';
322 
323 
324 print '<br>';
325 
326 
327 // Add javascript to make choice dynamic
328 print '<script type="text/javascript" language="javascript">
329 jQuery(document).ready(function() {
330  function init_selectors()
331  {
332  if (jQuery("#fillmanually:checked").val() == "fillmanually")
333  {
334  jQuery("#submitproduct").prop("disabled", true);
335  jQuery("#submitthirdparty").prop("disabled", true);
336  jQuery("#search_productid").prop("disabled", true);
337  jQuery("#socid").prop("disabled", true);
338  jQuery(".showforproductselector").hide();
339  jQuery(".showforthirdpartyselector").hide();
340  }
341  if (jQuery("#fillfromproduct:checked").val() == "fillfromproduct")
342  {
343  jQuery("#submitproduct").removeAttr("disabled");
344  jQuery("#submitthirdparty").prop("disabled", true);
345  jQuery("#search_productid").removeAttr("disabled");
346  jQuery("#socid").prop("disabled", true);
347  jQuery(".showforproductselector").show();
348  jQuery(".showforthirdpartyselector").hide();
349  }
350  if (jQuery("#fillfromthirdparty:checked").val() == "fillfromthirdparty")
351  {
352  jQuery("#submitproduct").prop("disabled", true);
353  jQuery("#submitthirdparty").removeAttr("disabled");
354  jQuery("#search_productid").prop("disabled", true);
355  jQuery("#socid").removeAttr("disabled");
356  jQuery(".showforproductselector").hide();
357  jQuery(".showforthirdpartyselector").show();
358  }
359  }
360  init_selectors();
361  jQuery(".radiobarcodeselect").click(function() {
362  init_selectors();
363  });
364 
365  function init_gendoc_button()
366  {
367  if (jQuery("#select_fk_barcode_type").val() > 0 && jQuery("#forbarcode").val())
368  {
369  jQuery("#submitformbarcodegen").removeAttr("disabled");
370  }
371  else
372  {
373  jQuery("#submitformbarcodegen").prop("disabled", true);
374  }
375  }
376  init_gendoc_button();
377  jQuery("#select_fk_barcode_type").change(function() {
378  init_gendoc_button();
379  });
380  jQuery("#forbarcode").keyup(function() {
381  init_gendoc_button()
382  });
383 });
384 </script>';
385 
386 // Checkbox to select from free text
387 print '<input id="fillmanually" type="radio" '.((!GETPOST("selectorforbarcode") || GETPOST("selectorforbarcode") == 'fillmanually') ? 'checked ' : '').'name="selectorforbarcode" value="fillmanually" class="radiobarcodeselect"> '.$langs->trans("FillBarCodeTypeAndValueManually").' &nbsp; ';
388 print '<br>';
389 
390 if (!empty($user->rights->produit->lire) || !empty($user->rights->service->lire))
391 {
392  print '<input id="fillfromproduct" type="radio" '.((GETPOST("selectorforbarcode") == 'fillfromproduct') ? 'checked ' : '').'name="selectorforbarcode" value="fillfromproduct" class="radiobarcodeselect"> '.$langs->trans("FillBarCodeTypeAndValueFromProduct").' &nbsp; ';
393  print '<br>';
394  print '<div class="showforproductselector">';
395  $form->select_produits(GETPOST('productid', 'int'), 'productid', '', '', 0, -1, 2, '', 0, array(), 0, '1', 0, 'minwidth400imp', 1);
396  print ' &nbsp; <input type="submit" id="submitproduct" name="submitproduct" class="button" value="'.(dol_escape_htmltag($langs->trans("GetBarCode"))).'">';
397  print '</div>';
398 }
399 
400 if (!empty($user->rights->societe->lire))
401 {
402  print '<input id="fillfromthirdparty" type="radio" '.((GETPOST("selectorforbarcode") == 'fillfromthirdparty') ? 'checked ' : '').'name="selectorforbarcode" value="fillfromthirdparty" class="radiobarcodeselect"> '.$langs->trans("FillBarCodeTypeAndValueFromThirdParty").' &nbsp; ';
403  print '<br>';
404  print '<div class="showforthirdpartyselector">';
405  print $form->select_company(GETPOST('socid', 'int'), 'socid', '', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
406  print ' &nbsp; <input type="submit" id="submitthirdparty" name="submitthirdparty" class="button showforthirdpartyselector" value="'.(dol_escape_htmltag($langs->trans("GetBarCode"))).'">';
407  print '</div>';
408 }
409 
410 print '<br>';
411 
412 if ($producttmp->id > 0)
413 {
414  print $langs->trans("BarCodeDataForProduct", '').' '.$producttmp->getNomUrl(1).'<br>';
415 }
416 if ($thirdpartytmp->id > 0)
417 {
418  print $langs->trans("BarCodeDataForThirdparty", '').' '.$thirdpartytmp->getNomUrl(1).'<br>';
419 }
420 
421 print '<div class="tagtable">';
422 
423 // Barcode type
424 print ' <div class="tagtr">';
425 print ' <div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
426 print $langs->trans("BarcodeType").' &nbsp; ';
427 print '</div><div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
428 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
429 $formbarcode = new FormBarCode($db);
430 print $formbarcode->selectBarcodeType($fk_barcode_type, 'fk_barcode_type', 1);
431 print '</div></div>';
432 
433 // Barcode value
434 print ' <div class="tagtr">';
435 print ' <div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
436 print $langs->trans("BarcodeValue").' &nbsp; ';
437 print '</div><div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
438 print '<input size="16" type="text" name="forbarcode" id="forbarcode" value="'.$forbarcode.'">';
439 print '</div></div>';
440 
441 /*
442 $barcodestickersmask=GETPOST('barcodestickersmask');
443 print '<br>'.$langs->trans("BarcodeStickersMask").':<br>';
444 print '<textarea cols="40" type="text" name="barcodestickersmask" value="'.GETPOST('barcodestickersmask').'">'.$barcodestickersmask.'</textarea>';
445 print '<br>';
446 */
447 
448 print '</div>';
449 
450 print '<br><input class="button" type="submit" id="submitformbarcodegen" '.((GETPOST("selectorforbarcode") && GETPOST("selectorforbarcode")) ? '' : 'disabled ').'value="'.$langs->trans("BuildPageToPrint").'">';
451 
452 print '</form>';
453 print '<br>';
454 
455 // End of page
456 llxFooter();
457 $db->close();
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class to manage products or services.
dol_now($mode= 'auto')
Return date for now.
setEventMessage($mesgs, $style= 'mesgs')
Set event message in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
llxHeader()
Empty header.
Definition: wrapper.php:45
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1)
Remove a file or several files with a mask.
Definition: files.lib.php:1144
Class to manage barcode HTML.
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:457
doc_label_pdf_create($db, $arrayofrecords, $modele, $outputlangs, $outputdir= '', $template= 'standardlabel', $filename= 'tmp_address_sheet.pdf')
Create a document onto disk according to template module.
print
Draft customers invoices.
Definition: index.php:89
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Class of a generic business object.
make_substitutions($text, $substitutionarray, $outputlangs=null)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=&gt;newva...
dol_htmloutput_errors($mesgstring= '', $mesgarray=array(), $keepembedded=0)
Print formated error messages to output (Used to show messages on html output).
llxFooter()
Empty footer.
Definition: wrapper.php:59
dol_mkdir($dir, $dataroot= '', $newmask=null)
Creation of a directory (this can create recursive subdir)
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the &quot;subst...