dolibarr 18.0.6
dolreceiptprinter.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2015-2021 Frédéric France <frederic.france@netlogic.fr>
3 * Copyright (C) 2020 Andreu Bisquerra <jove@bisquerra.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 <https://www.gnu.org/licenses/>.
17 * or see https://www.gnu.org/
18 */
19
25/*
26 * Tags for ticket template
27 *
28 * {dol_align_left} Left align text
29 * {dol_align_center} Center text
30 * {dol_align_right} Right align text
31 * {dol_use_font_a} Use font A of printer
32 * {dol_use_font_b} Use font B of printer
33 * {dol_use_font_c} Use font C of printer
34 * {dol_bold} Text Bold
35 * {dol_bold_disabled} Disable Text Bold
36 * {dol_double_height} Text double height
37 * {dol_double_width} Text double width
38 * {dol_default_height_width} Text default height and width
39 * {dol_underline} Underline text
40 * {dol_underline_disabled} Disable underline text
41 * {dol_cut_paper_full} Cut ticket completely
42 * {dol_cut_paper_partial} Cut ticket partially
43 * {dol_open_drawer} Open cash drawer
44 * {dol_beep} Activate buzzer
45 * {dol_beep_alternative} Activate buzzer (alternative mode)
46 * {dol_print_barcode} Print barcode
47 * {dol_print_logo} Print logo stored on printer. Example : <print_logo>32|32
48 * {dol_print_logo_old} Print logo stored on printer. Must be followed by logo code. For old printers.
49 * {dol_print_logo_old_cf} Print logo stored on printer. Must be followed by logo code. For old printers. May help for centering image.
50 * {dol_print_object_lines} Print object lines
51 * {dol_print_object_tax} Print object total tax
52 * {dol_print_object_local_tax} Print object local tax
53 * {dol_print_object_total} Print object total
54 * {dol_print_order_lines} Print order lines for Printer
55 * {dol_print_object_lines_with_notes} Print object lines with notes
56 * {dol_print_payment} Print payment method
57 * {dol_print_curr_date} Print the current date/time. Must be followed by format string.
58 *
59 * Code which can be placed everywhere
60 * <dol_value_date> Replaced by date AAAA-MM-DD
61 * <dol_value_date_time> Replaced by date and time AAAA-MM-DD HH:MM:SS
62 * <dol_value_year> Replaced by Year
63 * <dol_value_month_letters> Replaced by month in letters (example : november)
64 * <dol_value_month> Replaced by month number
65 * <dol_value_day> Replaced by day number
66 * <dol_value_day_letters> Replaced by day number
67 * <dol_value_currentdate> Replaced by current date and time
68 * <dol_value_currentdate_notime> Replaced by current date without time
69 * <dol_object_id> Replaced by object id
70 * <dol_object_ref> Replaced by object ref
71 * <dol_value_customer_firstname> Replaced by customer firstname
72 * <dol_value_customer_lastname> Replaced by customer name
73 * <dol_value_customer_mail> Replaced by customer mail
74 * <dol_value_customer_phone> Replaced by customer phone
75 * <dol_value_customer_mobile> Replaced by customer mobile
76 * <dol_value_customer_skype> Replaced by customer skype
77 * <dol_value_customer_tax_number> Replaced by customer VAT number
78 * <dol_value_customer_account_balance> Replaced by customer account balance
79 * <dol_value_mysoc_name> Replaced by mysoc name
80 * <dol_value_mysoc_address> Replaced by mysoc address
81 * <dol_value_mysoc_zip> Replaced by mysoc zip
82 * <dol_value_mysoc_town> Replaced by mysoc town
83 * <dol_value_mysoc_country> Replaced by mysoc country
84 * <dol_value_mysoc_idprof1> Replaced by mysoc idprof1
85 * <dol_value_mysoc_idprof2> Replaced by mysoc idprof2
86 * <dol_value_mysoc_idprof3> Replaced by mysoc idprof3
87 * <dol_value_mysoc_idprof4> Replaced by mysoc idprof4
88 * <dol_value_mysoc_idprof5> Replaced by mysoc idprof5
89 * <dol_value_mysoc_idprof6> Replaced by mysoc idprof6
90 * <dol_value_vendor_lastname> Replaced by vendor name
91 * <dol_value_vendor_firstname> Replaced by vendor firstname
92 * <dol_value_vendor_mail> Replaced by vendor mail
93 * <dol_value_customer_points> Replaced by customer points
94 * <dol_value_object_points> Replaced by number of points for this object
95 *
96 * Conditional code at line start (if then Print)
97 * <dol_print_if_customer> Print the line IF a customer is affected to the object
98 * <dol_print_if_vendor> Print the line IF a vendor is affected to the object
99 * <dol_print_if_happy_hour> Print the line IF Happy Hour
100 * <dol_print_if_num_object_unique> Print the line IF object is validated
101 * <dol_print_if_customer_points> Print the line IF customer points > 0
102 * <dol_print_if_object_points> Print the line IF points of the object > 0
103 * <dol_print_if_customer_tax_number> Print the line IF customer has vat number
104 * <dol_print_if_customer_account_balance_positive> Print the line IF customer balance > 0
105 *
106 */
107
108require_once DOL_DOCUMENT_ROOT.'/includes/mike42/escpos-php/autoload.php';
109use Mike42\Escpos\PrintConnectors\FilePrintConnector;
110use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;
111use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
112use Mike42\Escpos\PrintConnectors\CupsPrintConnector;
113use Mike42\Escpos\PrintConnectors\DummyPrintConnector;
114use Mike42\Escpos\CapabilityProfile;
115use Mike42\Escpos\Printer;
116use Mike42\Escpos\EscposImage;
117
121class dolReceiptPrinter extends Printer
122{
123 const CONNECTOR_DUMMY = 1;
124 const CONNECTOR_FILE_PRINT = 2;
125 const CONNECTOR_NETWORK_PRINT = 3;
126 const CONNECTOR_WINDOWS_PRINT = 4;
127 const CONNECTOR_CUPS_PRINT = 5;
128
132 public $db;
133
134 /*
135 * @var string[] array of tags
136 */
137 public $tags;
138 public $printer;
139 public $template;
140
145 public $orderprinter;
146
151 public $listprinters;
152
157 public $listprinterstemplates;
158
162 public $error = '';
163
167 public $errors = array();
168
174 public function __construct($db)
175 {
176 $this->db = $db;
177 $this->tags = array(
178 'dol_line_feed' => 'DOL_LINE_FEED',
179 'dol_line_feed_reverse' => 'DOL_LINE_FEED_REVERSE',
180 'dol_align_left' => 'DOL_ALIGN_LEFT',
181 'dol_align_center' => 'DOL_ALIGN_CENTER',
182 'dol_align_right' => 'DOL_ALIGN_RIGHT',
183 'dol_use_font_a' => 'DOL_USE_FONT_A',
184 'dol_use_font_b' => 'DOL_USE_FONT_B',
185 'dol_use_font_c' => 'DOL_USE_FONT_C',
186 'dol_bold' => 'DOL_BOLD',
187 'dol_bold_disabled' => 'DOL_BOLD_DISABLED',
188 'dol_double_height' => 'DOL_DOUBLE_HEIGHT',
189 'dol_double_width' => 'DOL_DOUBLE_WIDTH',
190 'dol_default_height_width' => 'DOL_DEFAULT_HEIGHT_WIDTH',
191 'dol_underline' => 'DOL_UNDERLINE',
192 'dol_underline_disabled' => 'DOL_UNDERLINE_DISABLED',
193 'dol_cut_paper_full' => 'DOL_CUT_PAPER_FULL',
194 'dol_cut_paper_partial' => 'DOL_CUT_PAPER_PARTIAL',
195 'dol_open_drawer' => 'DOL_OPEN_DRAWER',
196 'dol_beep' => 'DOL_BEEP',
197 'dol_beep_alternative' => 'DOL_BEEP_ALTERNATIVE',
198 'dol_print_text' => 'DOL_PRINT_TEXT',
199 'dol_print_barcode' => 'DOL_PRINT_BARCODE',
200 'dol_value_date' => 'DateInvoice',
201 'dol_value_date_time' => 'DateInvoiceWithTime',
202 'dol_value_year' => 'YearInvoice',
203 'dol_value_month_letters' => 'DOL_VALUE_MONTH_LETTERS',
204 'dol_value_month' => 'DOL_VALUE_MONTH',
205 'dol_value_day' => 'DOL_VALUE_DAY',
206 'dol_value_day_letters' => 'DOL_VALUE_DAY',
207 'dol_value_currentdate' => 'DOL_VALUE_CURRENTDATE',
208 'dol_value_currentdate_notime' => 'CurrentDateWithTime',
209 'dol_value_currentdate_letters' => 'DOL_VALUE_CURRENTDATE_LETTERS',
210 'dol_value_currentyear' => 'CurrentYear',
211 'dol_value_currentmonth_letters' => 'DOL_VALUE_CURRENT_MONTH_LETTERS',
212 'dol_value_currentmonth' => 'DOL_VALUE_CURRENT_MONTH',
213 'dol_value_currentday' => 'DOL_VALUE_CURRENT_DAY',
214 'dol_value_currentday_letters' => 'DOL_VALUE_CURRENT_DAY',
215 'dol_print_payment' => 'DOL_PRINT_PAYMENT',
216 'dol_print_curr_date' => 'DOL_PRINT_CURR_DATE',
217 'dol_print_logo' => 'DOL_PRINT_LOGO',
218 'dol_print_logo_old' => 'DOL_PRINT_LOGO_OLD',
219 'dol_print_logo_old_cf' => 'DOL_PRINT_LOGO_OLD_CF',
220 'dol_value_object_id' => 'InvoiceID',
221 'dol_value_object_ref' => 'InvoiceRef',
222 'dol_print_object_lines' => 'DOL_PRINT_OBJECT_LINES',
223 'dol_print_object_lines_with_notes' => 'DOL_PRINT_OBJECT_LINES_WITH_NOTES',
224 'dol_print_object_tax' => 'TotalVAT',
225 'dol_print_object_local_tax1' => 'TotalLT1',
226 'dol_print_object_local_tax2' => 'TotalLT2',
227 'dol_print_object_total' => 'Total',
228 'dol_print_object_number' => 'DOL_PRINT_OBJECT_NUMBER',
229 //'dol_value_object_points' => 'DOL_VALUE_OBJECT_POINTS',
230 'dol_print_order_lines' => 'DOL_PRINT_ORDER_LINES',
231 'dol_value_customer_firstname' => 'DOL_VALUE_CUSTOMER_FIRSTNAME',
232 'dol_value_customer_lastname' => 'DOL_VALUE_CUSTOMER_LASTNAME',
233 'dol_value_customer_mail' => 'DOL_VALUE_CUSTOMER_MAIL',
234 'dol_value_customer_phone' => 'DOL_VALUE_CUSTOMER_PHONE',
235 'dol_value_customer_skype' => 'DOL_VALUE_CUSTOMER_SKYPE',
236 'dol_value_customer_tax_number' => 'DOL_VALUE_CUSTOMER_TAX_NUMBER',
237 //'dol_value_customer_account_balance' => 'DOL_VALUE_CUSTOMER_ACCOUNT_BALANCE',
238 //'dol_value_customer_points' => 'DOL_VALUE_CUSTOMER_POINTS',
239 'dol_value_mysoc_name' => 'DOL_VALUE_MYSOC_NAME',
240 'dol_value_mysoc_address' => 'Address',
241 'dol_value_mysoc_zip' => 'Zip',
242 'dol_value_mysoc_town' => 'Town',
243 'dol_value_mysoc_country' => 'Country',
244 'dol_value_mysoc_idprof1' => 'ProfId1',
245 'dol_value_mysoc_idprof2' => 'ProfId2',
246 'dol_value_mysoc_idprof3' => 'ProfId3',
247 'dol_value_mysoc_idprof4' => 'ProfId4',
248 'dol_value_mysoc_idprof5' => 'ProfId5',
249 'dol_value_mysoc_idprof6' => 'ProfId6',
250 'dol_value_mysoc_tva_intra' => 'VATIntra',
251 'dol_value_mysoc_capital' => 'Capital',
252 'dol_value_mysoc_url' => 'Web',
253 'dol_value_vendor_lastname' => 'VendorLastname',
254 'dol_value_vendor_firstname' => 'VendorFirstname',
255 'dol_value_vendor_mail' => 'VendorEmail',
256 'dol_value_place' => 'DOL_VALUE_PLACE',
257 );
258 }
259
265 public function listPrinters()
266 {
267 global $conf;
268
269 $error = 0;
270 $line = 0;
271 $obj = array();
272
273 $sql = "SELECT rowid, name, fk_type, fk_profile, parameter";
274 $sql .= " FROM ".$this->db->prefix()."printer_receipt";
275 $sql .= " WHERE entity = ".((int) $conf->entity);
276
277 $resql = $this->db->query($sql);
278
279 if ($resql) {
280 $num = $this->db->num_rows($resql);
281 while ($line < $num) {
282 $row = $this->db->fetch_array($resql);
283 switch ($row['fk_type']) {
284 case 1:
285 $row['fk_type_name'] = 'CONNECTOR_DUMMY';
286 break;
287 case 2:
288 $row['fk_type_name'] = 'CONNECTOR_FILE_PRINT';
289 break;
290 case 3:
291 $row['fk_type_name'] = 'CONNECTOR_NETWORK_PRINT';
292 break;
293 case 4:
294 $row['fk_type_name'] = 'CONNECTOR_WINDOWS_PRINT';
295 break;
296 case 5:
297 $row['fk_type_name'] = 'CONNECTOR_CUPS_PRINT';
298 break;
299 default:
300 $row['fk_type_name'] = 'CONNECTOR_UNKNOWN';
301 break;
302 }
303 switch ($row['fk_profile']) {
304 case 0:
305 $row['fk_profile_name'] = 'PROFILE_DEFAULT';
306 break;
307 case 1:
308 $row['fk_profile_name'] = 'PROFILE_SIMPLE';
309 break;
310 case 2:
311 $row['fk_profile_name'] = 'PROFILE_EPOSTEP';
312 break;
313 case 3:
314 $row['fk_profile_name'] = 'PROFILE_P822D';
315 break;
316 default:
317 $row['fk_profile_name'] = 'PROFILE_STAR';
318 break;
319 }
320 $obj[] = $row;
321 $line++;
322 }
323 } else {
324 $error++;
325 $this->errors[] = $this->db->lasterror;
326 }
327
328 $this->listprinters = $obj;
329
330 return $error;
331 }
332
333
339 public function listPrintersTemplates()
340 {
341 global $conf;
342
343 $error = 0;
344 $line = 0;
345 $obj = array();
346
347 $sql = "SELECT rowid, name, template";
348 $sql .= " FROM ".$this->db->prefix()."printer_receipt_template";
349 $sql .= " WHERE entity = ".$conf->entity;
350
351 $resql = $this->db->query($sql);
352
353 if ($resql) {
354 $num = $this->db->num_rows($resql);
355 while ($line < $num) {
356 $obj[] = $this->db->fetch_array($resql);
357 $line++;
358 }
359 } else {
360 $error++;
361 $this->errors[] = $this->db->lasterror;
362 }
363
364 $this->listprinterstemplates = $obj;
365
366 return $error;
367 }
368
369
377 public function selectTypePrinter($selected = '', $htmlname = 'printertypeid')
378 {
379 global $langs;
380
381 $options = array(
382 1 => $langs->trans('CONNECTOR_DUMMY'),
383 2 => $langs->trans('CONNECTOR_FILE_PRINT'),
384 3 => $langs->trans('CONNECTOR_NETWORK_PRINT'),
385 4 => $langs->trans('CONNECTOR_WINDOWS_PRINT'),
386 5 => $langs->trans('CONNECTOR_CUPS_PRINT'),
387 );
388
389 $this->resprint = Form::selectarray($htmlname, $options, $selected);
390
391 return 0;
392 }
393
394
402 public function selectProfilePrinter($selected = '', $htmlname = 'printerprofileid')
403 {
404 global $langs;
405
406 $options = array(
407 0 => $langs->trans('PROFILE_DEFAULT'),
408 1 => $langs->trans('PROFILE_SIMPLE'),
409 2 => $langs->trans('PROFILE_EPOSTEP'),
410 3 => $langs->trans('PROFILE_P822D'),
411 4 => $langs->trans('PROFILE_STAR'),
412 );
413
414 $this->profileresprint = Form::selectarray($htmlname, $options, $selected);
415 return 0;
416 }
417
418
428 public function addPrinter($name, $type, $profile, $parameter)
429 {
430 global $conf;
431 $error = 0;
432 $sql = "INSERT INTO ".$this->db->prefix()."printer_receipt";
433 $sql .= " (name, fk_type, fk_profile, parameter, entity)";
434 $sql .= " VALUES ('".$this->db->escape($name)."', ".((int) $type).", ".((int) $profile).", '".$this->db->escape($parameter)."', ".((int) $conf->entity).")";
435 $resql = $this->db->query($sql);
436 if (!$resql) {
437 $error++;
438 $this->errors[] = $this->db->lasterror;
439 }
440 return $error;
441 }
442
453 public function updatePrinter($name, $type, $profile, $parameter, $printerid)
454 {
455 global $conf;
456 $error = 0;
457
458 $sql = "UPDATE ".$this->db->prefix()."printer_receipt";
459 $sql .= " SET name='".$this->db->escape($name)."'";
460 $sql .= ", fk_type=".((int) $type);
461 $sql .= ", fk_profile=".((int) $profile);
462 $sql .= ", parameter='".$this->db->escape($parameter)."'";
463 $sql .= " WHERE rowid=".((int) $printerid);
464
465 $resql = $this->db->query($sql);
466 if (!$resql) {
467 $error++;
468 $this->errors[] = $this->db->lasterror;
469 }
470 return $error;
471 }
472
479 public function deletePrinter($printerid)
480 {
481 global $conf;
482 $error = 0;
483 $sql = 'DELETE FROM '.$this->db->prefix().'printer_receipt';
484 $sql .= ' WHERE rowid='.((int) $printerid);
485 $resql = $this->db->query($sql);
486 if (!$resql) {
487 $error++;
488 $this->errors[] = $this->db->lasterror;
489 }
490 return $error;
491 }
492
500 public function addTemplate($name, $template)
501 {
502 global $conf;
503 $error = 0;
504 $sql = "INSERT INTO ".$this->db->prefix()."printer_receipt_template";
505 $sql .= " (name, template, entity) VALUES ('".$this->db->escape($name)."'";
506 $sql .= ", '".$this->db->escape($template)."', ".$conf->entity.")";
507 $resql = $this->db->query($sql);
508 if (!$resql) {
509 $error++;
510 $this->errors[] = $this->db->lasterror;
511 }
512 return $error;
513 }
514
521 public function deleteTemplate($templateid)
522 {
523 global $conf;
524 $error = 0;
525 $sql = 'DELETE FROM '.$this->db->prefix().'printer_receipt_template';
526 $sql .= " WHERE rowid = ".((int) $templateid);
527 $sql .= " AND entity = ".$conf->entity;
528 $resql = $this->db->query($sql);
529 if (!$resql) {
530 $error++;
531 $this->errors[] = $this->db->lasterror;
532 }
533 return $error;
534 }
535
544 public function updateTemplate($name, $template, $templateid)
545 {
546 global $conf;
547 $error = 0;
548
549 $sql = "UPDATE ".$this->db->prefix()."printer_receipt_template";
550 $sql .= " SET name='".$this->db->escape($name)."'";
551 $sql .= ", template='".$this->db->escape($template)."'";
552 $sql .= " WHERE rowid=".((int) $templateid);
553 $resql = $this->db->query($sql);
554 if (!$resql) {
555 $error++;
556 $this->errors[] = $this->db->lasterror;
557 }
558 return $error;
559 }
560
561
568 public function sendTestToPrinter($printerid)
569 {
570 global $conf;
571
572 $error = 0;
573 $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo_bw.png');
574 //$this->profile = CapabilityProfile::load("TM-T88IV");
575 $ret = $this->initPrinter($printerid);
576 if ($ret > 0) {
577 setEventMessages($this->error, $this->errors, 'errors');
578 } else {
579 try {
580 $this->printer->bitImage($img);
581 $this->printer->text("Hello World!\n");
582 $testStr = "1234567890";
583 $this->printer->barcode($testStr);
584 //$this->printer->qrcode($testStr, Printer::QR_ECLEVEL_M, 5, Printer::QR_MODEL_1);
585 $this->printer->text("Most simple example\n");
586 $this->printer->feed();
587 $this->printer->cut();
588
589 // If is DummyPrintConnector send to log to debugging
590 if ($this->printer->connector instanceof DummyPrintConnector) {
591 $data = $this->printer->connector->getData();
592 dol_syslog($data);
593 }
594 $this->printer->close();
595 } catch (Exception $e) {
596 $this->errors[] = $e->getMessage();
597 $error++;
598 }
599 }
600 return $error;
601 }
602
611 public function sendToPrinter($object, $templateid, $printerid)
612 {
613 global $conf, $mysoc, $langs, $user;
614
615 $langs->load('bills');
616
617 $error = 0;
618 $ret = $this->loadTemplate($templateid);
619 $now = dol_now('tzuser');
620 // tags a remplacer par leur valeur avant de parser (dol_value_xxx)
621 $this->template = str_replace('{dol_value_object_id}', $object->id, $this->template);
622 $this->template = str_replace('{dol_value_object_ref}', $object->ref, $this->template);
623 //$this->template = str_replace('<dol_value_object_points>', $object->points, $this->template);
624 $this->template = str_replace('{dol_value_date}', dol_print_date($object->date, 'day'), $this->template);
625 $this->template = str_replace('{dol_value_date_time}', dol_print_date($object->date, 'dayhour'), $this->template);
626 $this->template = str_replace('{dol_value_year}', dol_print_date($object->date, '%Y'), $this->template);
627 $this->template = str_replace('{dol_value_month_letters}', $langs->trans("Month".dol_print_date($object->date, '%m')), $this->template);
628 $this->template = str_replace('{dol_value_month}', dol_print_date($object->date, '%m'), $this->template);
629 $this->template = str_replace('{dol_value_day}', dol_print_date($object->date, '%d'), $this->template);
630 $this->template = str_replace('{dol_value_day_letters}', $langs->trans("Day".dol_print_date($object->date, '%m')[1]), $this->template);
631
632 $this->template = str_replace('{dol_value_currentdate}', dol_print_date($now, 'dayhour'), $this->template);
633 $this->template = str_replace('{dol_value_currentdate_notime}', dol_print_date($now, 'day'), $this->template);
634 $this->template = str_replace('{dol_value_currentdate_letters}', dol_print_date($now, 'dayhourtext'), $this->template);
635 $this->template = str_replace('{dol_value_currentyear}', dol_print_date($now, '%Y'), $this->template);
636 $this->template = str_replace('{dol_value_currentmonth_letters}', $langs->trans("Month".dol_print_date($now, '%m')), $this->template);
637 $this->template = str_replace('{dol_value_currentmonth}', dol_print_date($now, '%m'), $this->template);
638 $this->template = str_replace('{dol_value_currentday}', dol_print_date($now, '%d'), $this->template);
639 $this->template = str_replace('{dol_value_currentday_letters}', $langs->trans("Day".dol_print_date($now, '%m')[1]), $this->template);
640
641 $this->template = str_replace('{dol_value_customer_firstname}', $object->thirdparty->firstname, $this->template);
642 $this->template = str_replace('{dol_value_customer_lastname}', $object->thirdparty->lastname, $this->template);
643 $this->template = str_replace('{dol_value_customer_mail}', $object->thirdparty->email, $this->template);
644 $this->template = str_replace('{dol_value_customer_phone}', $object->thirdparty->phone, $this->template);
645 //$this->template = str_replace('<dol_value_customer_mobile>', $object->thirdparty->mobile, $this->template);
646 $this->template = str_replace('{dol_value_customer_tax_number}', $object->thirdparty->tva_intra, $this->template);
647 //$this->template = str_replace('<dol_value_customer_account_balance>', $object->customer_account_balance, $this->template);
648 //$this->template = str_replace('<dol_value_customer_points>', $object->customer_points, $this->template);
649
650 $this->template = str_replace('{dol_value_mysoc_name}', $mysoc->name, $this->template);
651 $this->template = str_replace('{dol_value_mysoc_address}', $mysoc->address, $this->template);
652 $this->template = str_replace('{dol_value_mysoc_zip}', $mysoc->zip, $this->template);
653 $this->template = str_replace('{dol_value_mysoc_town}', $mysoc->town, $this->template);
654 $this->template = str_replace('{dol_value_mysoc_country}', $mysoc->country, $this->template);
655 $this->template = str_replace('{dol_value_mysoc_idprof1}', $mysoc->idprof1, $this->template);
656 $this->template = str_replace('{dol_value_mysoc_idprof2}', $mysoc->idprof2, $this->template);
657 $this->template = str_replace('{dol_value_mysoc_idprof3}', $mysoc->idprof3, $this->template);
658 $this->template = str_replace('{dol_value_mysoc_idprof4}', $mysoc->idprof4, $this->template);
659 $this->template = str_replace('{dol_value_mysoc_idprof5}', $mysoc->idprof5, $this->template);
660 $this->template = str_replace('{dol_value_mysoc_idprof6}', $mysoc->idprof6, $this->template);
661 $this->template = str_replace('{dol_value_mysoc_tva_intra}', $mysoc->tva_intra, $this->template);
662 $this->template = str_replace('{dol_value_mysoc_capital}', $mysoc->capital, $this->template);
663 $this->template = str_replace('{dol_value_mysoc_url}', $mysoc->url, $this->template);
664
665 $this->template = str_replace('{dol_value_vendor_firstname}', $user->firstname, $this->template);
666 $this->template = str_replace('{dol_value_vendor_lastname}', $user->lastname, $this->template);
667 $this->template = str_replace('{dol_value_vendor_mail}', $user->email, $this->template);
668
669 // parse template
670 $this->template = str_replace("{", "<", $this->template);
671 $this->template = str_replace("}", ">", $this->template);
672 $p = xml_parser_create();
673 xml_parse_into_struct($p, $this->template, $vals, $index);
674 xml_parser_free($p);
675 //print '<pre>'.print_r($index, true).'</pre>';
676 //print '<pre>'.print_r($vals, true).'</pre>';
677 // print ticket
678 $level = 0;
679 $nbcharactbyline = (!empty($conf->global->RECEIPT_PRINTER_NB_CHARACT_BY_LINE) ? $conf->global->RECEIPT_PRINTER_NB_CHARACT_BY_LINE : 48);
680 $ret = $this->initPrinter($printerid);
681 if ($ret > 0) {
682 setEventMessages($this->error, $this->errors, 'errors');
683 } else {
684 $nboflines = count($vals);
685 for ($tplline = 0; $tplline < $nboflines; $tplline++) {
686 //var_dump($vals[$tplline]['value']);
687 switch ($vals[$tplline]['tag']) {
688 case 'DOL_PRINT_TEXT':
689 $this->printer->text($vals[$tplline]['value']);
690 break;
691 case 'DOL_PRINT_OBJECT_LINES':
692 foreach ($object->lines as $line) {
693 if ($line->fk_product) {
694 $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - strlen($line->subprice) - 10 - 1;
695 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
696 $this->printer->text($line->ref . $spaces . $line->qty . str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT) . ' ' . str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT) . "\n");
697 $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n \n");
698 } else {
699 $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - strlen($line->subprice) - 10 - 1;
700 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
701 $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT).' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
702 }
703 }
704 break;
705 case 'DOL_PRINT_OBJECT_LINES_WITH_NOTES':
706 foreach ($object->lines as $line) {
707 if ($line->fk_product) {
708 $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1;
709 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
710 $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
711 $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n");
712 $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - 10 - 1;
713 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
714 $this->printer->text($line->description."\n");
715 } else {
716 $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - 10 - 1;
717 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
718 $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
719 }
720 }
721 break;
722 case 'DOL_PRINT_OBJECT_TAX':
723 //var_dump($object);
724 $vatarray = array();
725 foreach ($object->lines as $line) {
726 $vatarray[$line->tva_tx] += $line->total_tva;
727 }
728 foreach ($vatarray as $vatkey => $vatvalue) {
729 $spacestoadd = $nbcharactbyline - strlen($vatkey) - 12;
730 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
731 $this->printer->text($spaces.$vatkey.'% '.str_pad(price($vatvalue), 10, ' ', STR_PAD_LEFT)."\n");
732 }
733 break;
734 case 'DOL_PRINT_OBJECT_TAX1':
735 //var_dump($object);
736 $total_localtax1 = 0;
737 foreach ($object->lines as $line) {
738 $total_localtax1 += $line->total_localtax1;
739 }
740 $this->printer->text(str_pad(price($total_localtax1), 10, ' ', STR_PAD_LEFT)."\n");
741 break;
742 case 'DOL_PRINT_OBJECT_TAX2':
743 //var_dump($object);
744 $total_localtax2 = 0;
745 foreach ($object->lines as $line) {
746 $total_localtax2 += $line->total_localtax2;
747 }
748 $this->printer->text(str_pad(price($total_localtax2), 10, ' ', STR_PAD_LEFT)."\n");
749 break;
750 case 'DOL_PRINT_OBJECT_TOTAL':
751 $title = $langs->trans('TotalHT');
752 $spacestoadd = $nbcharactbyline - strlen($title) - 10;
753 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
754 $this->printer->text($title.$spaces.str_pad(price($object->total_ht), 10, ' ', STR_PAD_LEFT)."\n");
755 $title = $langs->trans('TotalVAT');
756 $spacestoadd = $nbcharactbyline - strlen($title) - 10;
757 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
758 $this->printer->text($title.$spaces.str_pad(price($object->total_tva), 10, ' ', STR_PAD_LEFT)."\n");
759 $title = $langs->trans('TotalTTC');
760 $spacestoadd = $nbcharactbyline - strlen($title) - 10;
761 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
762 $this->printer->text($title.$spaces.str_pad(price($object->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
763 break;
764 case 'DOL_PRINT_CURR_DATE':
765 if (strlen($vals[$tplline]['value'])<2) $this->printer->text(date('d/m/Y H:i:s')."\n");
766 else $this->printer->text(date($vals[$tplline]['value'])."\n");
767 break;
768 case 'DOL_LINE_FEED':
769 $this->printer->feed();
770 break;
771 case 'DOL_LINE_FEED_REVERSE':
772 $this->printer->feedReverse();
773 break;
774 case 'DOL_ALIGN_CENTER':
775 $this->printer->setJustification(Printer::JUSTIFY_CENTER);
776 break;
777 case 'DOL_ALIGN_RIGHT':
778 $this->printer->setJustification(Printer::JUSTIFY_RIGHT);
779 break;
780 case 'DOL_ALIGN_LEFT':
781 $this->printer->setJustification(Printer::JUSTIFY_LEFT);
782 break;
783 case 'DOL_OPEN_DRAWER':
784 $this->printer->pulse();
785 break;
786 case 'DOL_ACTIVATE_BUZZER':
787 //$this->printer->buzzer();
788 break;
789 case 'DOL_PRINT_BARCODE':
790 // $vals[$tplline]['value'] -> barcode($content, $type)
791 // var_dump($vals[$tplline]['value']);
792 try {
793 $this->printer->barcode($vals[$tplline]['value']);
794 } catch (Exception $e) {
795 $this->errors[] = 'Invalid Barcode value: '.$vals[$tplline]['value'];
796 $error++;
797 }
798 break;
799 case 'DOL_PRINT_LOGO':
800 $img = EscposImage::load(DOL_DATA_ROOT.'/mycompany/logos/'.$mysoc->logo);
801 $this->printer->graphics($img);
802 break;
803 case 'DOL_PRINT_LOGO_OLD':
804 $img = EscposImage::load(DOL_DATA_ROOT.'/mycompany/logos/'.$mysoc->logo);
805 $this->printer->bitImage($img);
806 break;
807 case 'DOL_PRINT_LOGO_OLD_CF':
808 $img = EscposImage::load(DOL_DATA_ROOT.'/mycompany/logos/'.$mysoc->logo);
809 $this->printer->bitImageColumnFormat($img);
810 break;
811 case 'DOL_PRINT_QRCODE':
812 // $vals[$tplline]['value'] -> qrCode($content, $ec, $size, $model)
813 $this->printer->qrcode($vals[$tplline]['value']);
814 break;
815 case 'DOL_CUT_PAPER_FULL':
816 $this->printer->cut(Printer::CUT_FULL);
817 break;
818 case 'DOL_CUT_PAPER_PARTIAL':
819 $this->printer->cut(Printer::CUT_PARTIAL);
820 break;
821 case 'DOL_USE_FONT_A':
822 $this->printer->setFont(Printer::FONT_A);
823 break;
824 case 'DOL_USE_FONT_B':
825 $this->printer->setFont(Printer::FONT_B);
826 break;
827 case 'DOL_USE_FONT_C':
828 $this->printer->setFont(Printer::FONT_C);
829 break;
830 case 'DOL_BOLD':
831 $this->printer->setEmphasis(true);
832 break;
833 case 'DOL_BOLD_DISABLED':
834 $this->printer->setEmphasis(false);
835 break;
836 case 'DOL_DOUBLE_HEIGHT':
837 $this->printer->setTextSize(1, 2);
838 break;
839 case 'DOL_DOUBLE_WIDTH':
840 $this->printer->setTextSize(2, 1);
841 break;
842 case 'DOL_DEFAULT_HEIGHT_WIDTH':
843 $this->printer->setTextSize(1, 1);
844 break;
845 case 'DOL_UNDERLINE':
846 $this->printer->setUnderline(true);
847 break;
848 case 'DOL_UNDERLINE_DISABLED':
849 $this->printer->setUnderline(false);
850 break;
851 case 'DOL_BEEP':
852 $this->printer->getPrintConnector() -> write("\x1e");
853 break;
854 case 'DOL_BEEP_ALTERNATIVE': //if DOL_BEEP not works
855 $this->printer->getPrintConnector() -> write(Printer::ESC . "B" . chr(4) . chr(1));
856 break;
857 case 'DOL_PRINT_ORDER_LINES':
858 foreach ($object->lines as $line) {
859 if ($line->special_code == $this->orderprinter) {
860 $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1;
861 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
862 $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
863 $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n");
864 }
865 }
866 break;
867 case 'DOL_PRINT_PAYMENT':
868 $sql = "SELECT p.pos_change as pos_change, p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
869 $sql .= " cp.code";
870 $sql .= " FROM ".$this->db->prefix()."paiement_facture as pf, ".$this->db->prefix()."paiement as p";
871 $sql .= " LEFT JOIN ".$this->db->prefix()."c_paiement as cp ON p.fk_paiement = cp.id";
872 $sql .= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".((int) $object->id);
873 $sql .= " ORDER BY p.datep";
874 $resql = $this->db->query($sql);
875 if ($resql) {
876 $num = $this->db->num_rows($resql);
877 $i = 0;
878 while ($i < $num) {
879 $row = $this->db->fetch_object($resql);
880 $spacestoadd = $nbcharactbyline - strlen($langs->transnoentitiesnoconv("PaymentTypeShort".$row->code)) - 12;
881 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
882 $amount_payment = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount;
883 if ($row->code == "LIQ") {
884 $amount_payment = $amount_payment + $row->pos_change; // Show amount with excess received if is cash payment
885 }
886 $this->printer->text($spaces.$langs->transnoentitiesnoconv("PaymentTypeShort".$row->code).' '.str_pad(price($amount_payment), 10, ' ', STR_PAD_LEFT)."\n");
887 if ($row->code == "LIQ" && $row->pos_change > 0) { // Print change only in cash payments
888 $spacestoadd = $nbcharactbyline - strlen($langs->trans("Change")) - 12;
889 $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0);
890 $this->printer->text($spaces.$langs->trans("Change").' '.str_pad(price($row->pos_change), 10, ' ', STR_PAD_LEFT)."\n");
891 }
892 $i++;
893 }
894 }
895 break;
896 case 'DOL_VALUE_PLACE':
897 $sql = "SELECT floor, label FROM ".$this->db->prefix()."takepos_floor_tables where rowid=".((int) str_replace(")", "", str_replace("(PROV-POS".$_SESSION["takeposterminal"]."-", "", $object->ref)));
898 $resql = $this->db->query($sql);
899 $obj = $this->db->fetch_object($resql);
900 if ($obj) {
901 $this->printer->text($obj->label);
902 }
903 break;
904 default:
905 $this->printer->text($vals[$tplline]['tag']);
906 $this->printer->text($vals[$tplline]['value']);
907 $this->errors[] = 'UnknowTag: &lt;'.strtolower($vals[$tplline]['tag']).'&gt;';
908 $error++;
909 break;
910 }
911 }
912 // If is DummyPrintConnector send to log to debugging
913 if ($this->printer->connector instanceof DummyPrintConnector || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") {
914 $data = $this->printer->connector->getData();
915 if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") {
916 echo rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
917 }
918 dol_syslog($data);
919 }
920 // Close and print
921 $this->printer->close();
922 }
923 return $error;
924 }
925
932 public function loadTemplate($templateid)
933 {
934 global $conf;
935 $error = 0;
936 $sql = "SELECT template";
937 $sql .= " FROM ".$this->db->prefix()."printer_receipt_template";
938 $sql .= " WHERE rowid = ".((int) $templateid);
939 $sql .= " AND entity = ".$conf->entity;
940 $resql = $this->db->query($sql);
941 if ($resql) {
942 $obj = $this->db->fetch_array($resql);
943 } else {
944 $error++;
945 $this->errors[] = $this->db->lasterror;
946 }
947 if (empty($obj)) {
948 $error++;
949 $this->errors[] = 'TemplateDontExist';
950 } else {
951 $this->template = $obj['0'];
952 }
953
954 return $error;
955 }
956
957
964 public function initPrinter($printerid)
965 {
966 global $conf;
967 if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") {
968 $this->connector = new DummyPrintConnector();
969 $this->printer = new Printer($this->connector, $this->profile);
970 return;
971 }
972 $error = 0;
973 $sql = "SELECT rowid, name, fk_type, fk_profile, parameter";
974 $sql .= " FROM ".$this->db->prefix()."printer_receipt";
975 $sql .= " WHERE rowid = ".((int) $printerid);
976 $sql .= " AND entity = ".((int) $conf->entity);
977 $resql = $this->db->query($sql);
978 if ($resql) {
979 $obj = $this->db->fetch_array($resql);
980 if (empty($obj)) {
981 $error++;
982 $this->errors[] = 'PrinterDontExist';
983 }
984 if (!$error) {
985 $parameter = (isset($obj['parameter']) ? $obj['parameter'] : '');
986 try {
987 $type = $obj['fk_type'];
988 switch ($type) {
989 case 1:
990 $this->connector = new DummyPrintConnector();
991 break;
992 case 2:
993 $this->connector = new FilePrintConnector($parameter);
994 break;
995 case 3:
996 $parameters = explode(':', $parameter);
997 $this->connector = new NetworkPrintConnector($parameters[0], $parameters[1]);
998 break;
999 case 4: // LPT1, smb://...
1000 $this->connector = new WindowsPrintConnector(dol_sanitizePathName($parameter));
1001 break;
1002 case 5:
1003 $this->connector = new CupsPrintConnector($parameter);
1004 break;
1005 default:
1006 $this->connector = 'CONNECTOR_UNKNOWN';
1007 break;
1008 }
1009 $this->printer = new Printer($this->connector, $this->profile);
1010 } catch (Exception $e) {
1011 $this->errors[] = $e->getMessage();
1012 $error++;
1013 }
1014 }
1015 } else {
1016 $error++;
1017 $this->errors[] = $this->db->lasterror;
1018 }
1019
1020 return $error;
1021 }
1022}
static selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='minwidth75', $addjscombo=1, $moreparamonempty='', $disablebademail=0, $nohtmlescape=0)
Return a HTML select string, built from an array of key+value.
Class to manage Receipt Printers.
selectTypePrinter($selected='', $htmlname='printertypeid')
Form to Select type printer.
addPrinter($name, $type, $profile, $parameter)
Function to Add a printer in db.
updatePrinter($name, $type, $profile, $parameter, $printerid)
Function to Update a printer in db.
sendToPrinter($object, $templateid, $printerid)
Function to Print Receipt Ticket.
listPrinters()
List printers into the array ->listprinters.
loadTemplate($templateid)
Function to load Template.
updateTemplate($name, $template, $templateid)
Function to Update a printer template in db.
sendTestToPrinter($printerid)
Function to Send Test page to Printer.
initPrinter($printerid)
Function Init Printer.
deleteTemplate($templateid)
Function to delete a printer template in db.
deletePrinter($printerid)
Function to Delete a printer from db.
selectProfilePrinter($selected='', $htmlname='printerprofileid')
Form to Select Profile printer.
addTemplate($name, $template)
Function to add a printer template in db.
listPrintersTemplates()
List printers templates.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_sanitizePathName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a path name.