assets/s2dipdfdoc.php /// Art: Shop Business Logic /// Inhalt: Klasse pdfdoc /// Beschreibung: Business Logic für die Erstellung von PDF Dokumenten /// Benötigt: config.php /// CCML-Parsing: nein /// ////////////////////////////////////////////////////////////////////////////////////////// /// /// Letzte Änderungen: /// 17.07.2010 Präfixe eingebaut /// 04.08.2010 Kundendfinierte Felder Footer und Ende Rechnung /// 05.08.2010 Positionierung bei ohne Slogan korrigiert /// 06.08.2010 MwStbefreiung angepasst /// 08.08.2010 Referenz Anpassung für PHP 4 /// ////////////////////////////////////////////////////////////////////////////////////////// ///<08.08.2010/7.0.1.10/> if (!defined('SHOP_TO_DATE')) die('Forbidden'); include_once(CC_INCLUDE_FPDF); class pdfdoc extends FPDF { var $MODE_BILL = 'bi'; var $MODE_CONFIRMATION = 'oc'; var $mode; var $filekey; // Key zur Generierung der Dateinamen var $filepath; // Pfad zum Speichern der Dokumente var $pdf; var $fontdata; // Konfiguration in mm bei A4 var $borderLeft = 20; var $borderRight = 15; var $lineLeftX = 10; var $lineRightX = 200; var $borderTop = 15; var $borderBottom = 15; var $colPadding = 10; var $logoHeight = 15; var $colx1 = null; var $colx2 = null; var $colWidth = null; var $bold = false; // Konstruktor function pdfdoc($filekey, $filepath, &$order) { $this->filekey = $filekey; $this->filepath = $filepath; $this->order = &$order; $this->pageWidth = 210 - $this->borderLeft - $this->borderRight; $this->colWidth = round(($this->pageWidth - $this->colPadding) / 2); $this->col1x = $this->borderLeft; $this->col2x = $this->borderLeft + $this->colWidth + $this->colPadding; $this->fontdata = array( 'Arial' => array( 'Arial', 'arial.php', 'arialbd.php', ), 'Tahoma' => array( 'Tahoma', 'tahoma.php', 'tahomabd.php', ), 'Verdana' => array( 'Verdana', 'verdana.php', 'verdanab.php', ), 'Times New Roman' => array( 'Times', 'times.php', 'timesbd.php' ), 'Trebuchet MS' => array( 'Trebuchet', 'trebuc.php', 'trebucbd.php' ) ); } // Dateiname generieren function filename($mode = null) { if ($mode) $this->mode = $mode; return $this->filepath.md5($this->order->order_id . $this->order->order_id_prefix . $this->filekey . $this->mode); } // Name generieren function name($mode = null) { if ($mode) $this->mode = $mode; return ($this->mode == $this->MODE_BILL ? CC_RESSOURCE_BILL . '_' . $this->order->bill_id_prefix . $this->order->bill_id : CC_RESSOURCE_CONFIRMATION . '_' . $this->order->order_id_prefix . $this->order->order_id ) . CC_SITE_PDFEXTENSION; } // PDF anzeigen function show($mode) { if (CC_SITE_BILLHASLEFTTHEBUILDING) return; $this->verify($mode); header("Content-type: application/pdf"); header('Content-Disposition: attachment; filename="' . $this->name() . '"'); readfile($this->filename()); exit; } // PDF wiederherstellen falls nicht mehr vorhanden function verify($mode) { $this->mode = $mode; if (!file_exists($filename = $this->filename())) { $this->generate($mode); } } function _mySetFont($bold) { if ($bold !== null) $this->bold = $bold; $this->SetFont($this->fontdata[CC_SITE_PDF_FONTFACE][0], $bold ? 'B' : '', floor(CC_SITE_PDF_FONTSIZE)); } function _mySetFontSlogan() { $this->SetFont($this->fontdata[CC_SITE_PDF_FONTFACE][0], '', floor(CC_SITE_PDF_FONTSIZESLOGAN)); } function generate($mode, $recover = false) { $this->mode = $mode; if (!$recover && $mode == $this->MODE_BILL && !$this->order->bill_id) { $this->order->set_bill_data(); $this->order->store(); } $this->FPDF(); $this->SetAuthor('shop to date 7'); $this->SetCreator('s2d7 PDF Generator by etor e.K. (Volker Sauer)'); if ($this->mode == $this->MODE_BILL) $this->SetTitle(CC_RESSOURCE_BILL . ' '.$this->order->bill_id_prefix.$this->order->bill_id); else if ($this->mode == $this->MODE_CONFIRMATION) $this->SetTitle(CC_RESSOURCE_CONFIRMATION . ' '.$this->order->order_id_prefix.$this->order->order_id); $this->SetDisplayMode('fullpage'); if (CC_SITE_PDF_HEAD_LOGO) $this->size = getimagesize(CC_SITE_PDF_HEAD_LOGO); if (CC_SITE_BILLHASLEFTTHEBUILDING) return; $height = array( 8 => 0.3527 * CC_SITE_PDF_FONTSIZE * 1.3, 9 => 0.3527 * CC_SITE_PDF_FONTSIZE * 1.3, 10 => 0.3527 * CC_SITE_PDF_FONTSIZE * 1.3, 11 => 0.3527 * CC_SITE_PDF_FONTSIZE * 1.3, 12 => 0.3527 * CC_SITE_PDF_FONTSIZE * 1.3, ); $this->cellHeight = $height[CC_SITE_PDF_FONTSIZE]; $this->cellPadding = $this->cellHeight; // Basiswerte $this->AddFont($this->fontdata[CC_SITE_PDF_FONTFACE][0], '', $this->fontdata[CC_SITE_PDF_FONTFACE][1]); $this->AddFont($this->fontdata[CC_SITE_PDF_FONTFACE][0], 'B', $this->fontdata[CC_SITE_PDF_FONTFACE][2]); $this->_mySetFont(false); // Footerhöhe berechnen if (strlen(CC_SITE_PDF_FOOTER)) { $lines = 2; $footerArray = explode('
', CC_SITE_PDF_FOOTER); foreach ($footerArray as $line) { $lines++; $wordQueue = ''; foreach (explode(' ', $line) as $word) { if ($this->getStringWidth($wordQueue . ' ' . $word) > $this->pageWidth) { $lines++; $wordQueue = $word; } else $wordQueue .= ' ' . $word; } } $this->footerHeight = $this->cellHeight * $lines + $this->borderBottom; $this->SetAutoPageBreak(true, $this->footerHeight); } else { $this->footerHeight = 0; $this->SetAutoPageBreak(true, $this->borderBottom); } $this->SetMargins($this->borderLeft, $this->borderTop, $this->borderRight); $this->SetDrawColor(0, 0, 0); $this->SetFillColor(255, 255, 255); #$this->SetFillColor(200, 200, 200); $this->SetLineWidth(0.3); $this->AddPage('P', 'A4'); /////////////////////////////////////////////////////////////// // Identifikationsblock (nur erste Seite) // Überschrift $this->_mySetFontSlogan(); $this->Cell(0, floor($this->cellHeight * 1.5), $this->mode == $this->MODE_BILL ? CC_RESSOURCE_BILL : CC_RESSOURCE_CONFIRMATION, 0, 1, 'L'); $this->_mySetFont(null); $this->Ln(); $y = $this->GetY(); if ($this->mode == $this->MODE_BILL) { // Rechnungsdatum $this->Cell($this->colWidth, $this->cellHeight, CC_RESSOURCE_BILLDATE . ': '. format::date($this->order->bill_date), 0, 1, 'L'); // Rechnungsnummer $this->Cell($this->colWidth, $this->cellHeight, CC_RESSOURCE_BILLID . ': '. $this->order->bill_id_prefix . $this->order->bill_id, 0, 1, 'L'); } // Auftragsdatum $this->SetXY($this->col2x, $y); $this->Cell($this->colWidth, $this->cellHeight, CC_RESSOURCE_ORDERDATE . ': '. format::date($this->order->order_date) . ' ' . $this->order->order_time, 0, 2, 'L'); // Auftragsnummer $this->Cell($this->colWidth, $this->cellHeight, CC_RESSOURCE_ORDERID . ': '. $this->order->order_id_prefix . $this->order->order_id, 0, 1, 'L'); /////////////////////////////////////////////////////////////// // Empfängerblock (nur erste Seite) // Name und Adresse des Empfängers $this->Ln(); $y = $this->GetY(); if ($this->order->client->deviating_shipping_address) $this->Ln(); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->salutation, 0, 'L'); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->firstname . ' ' . $this->order->client->lastname, 0, 'L'); if ($this->order->client->company) $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->company, 0, 'L'); else if ($this->order->client->deviating_shipping_address && $this->order->client->shipping_company) $this->Ln(); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->street . ' ' . $this->order->client->streetnumber, 0, 'L'); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->zip . ' ' . $this->order->client->city, 0, 'L'); $this->MultiCell($this->colWidth, $this->cellHeight, substr($this->order->client->country, 11), 0, 'L'); $y2 = $this->GetY(); if ($this->order->client->deviating_shipping_address) { $this->SetXY($this->col2x, $y); $this->_mySetFont(true); $this->Cell($this->colWidth, $this->cellHeight, CC_RESSOURCE_DELIVERYADDRESS, 0, 2, 'L'); $this->_mySetFont(false); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->shipping_salutation, 0, 'L'); $this->SetX($this->col2x); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->shipping_firstname . ' ' . $this->order->client->shipping_lastname, 0, 'L'); $this->SetX($this->col2x); if ($this->order->client->shipping_company) $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->shipping_company, 0, 'L'); else if ($this->order->client->company) $this->SetY($this->GetY() + $this->cellHeight); $this->SetX($this->col2x); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->shipping_street . ' ' . $this->order->client->shipping_streetnumber, 0, 'L'); $this->SetX($this->col2x); $this->MultiCell($this->colWidth, $this->cellHeight, $this->order->client->shipping_zip . ' ' . $this->order->client->shipping_city, 0, 'L'); $this->SetX($this->col2x); $this->MultiCell($this->colWidth, $this->cellHeight, substr($this->order->client->shipping_country, 11), 0, 'L'); $y2 = max($y2, $this->GetY()); } $this->SetY($y2); $this->Ln(); $this->Ln(); /////////////////////////////////////////////////////////////// // Positionsblock (seitenweise) $y = 0; $w_num = 0; $w_vat = 0; $w_price = 0; $w_priceall = 0; // Breiten berechnen foreach($this->order->items as $item) { $w_num = max( $this->GetStringWidth(format::quantity($item->quantity, $item->qprecision) . ' ' . $item->unit), $this->GetStringWidth(CC_RESSOURCE_BASKETQUANTITY), $w_num ); $w_vat = max( $this->GetStringWidth(format::vat($item->vat)), $this->GetStringWidth(CC_RESSOURCE_BASKETVAT), $w_vat ); $w_price = max( $this->GetStringWidth(format::price($item->price, $this->order->currency)), $this->GetStringWidth(CC_RESSOURCE_BASKETPRICEONE), $w_price ); $w_priceall = max( $this->GetStringWidth(format::price($item->price * $item->quantity, $this->order->currency)), $w_priceall ); } $this->_mySetFont(true); $w_priceall = max( $this->GetStringWidth(format::price($this->order->get_subtotal(), $this->order->currency)), $this->GetStringWidth(format::price($this->order->get_subtotal() - $this->order->get_rebate() + $this->order->get_shipping_cost() + $this->order->get_payment_cost(), $this->order->currency)), $this->GetStringWidth(CC_RESSOURCE_BASKETPRICEALL), $w_priceall ); if (CC_SITE_B2B) $w_priceall = max( $this->GetStringWidth(format::price($this->order->get_subtotal() - $this->order->get_rebate() + $this->order->get_shipping_cost() + $this->order->get_payment_cost() + $this->order->get_totalvat(), $this->order->currency)), $w_priceall ); $this->_mySetFont(false); $w_num += $this->cellPadding; $w_vat += $this->cellPadding; $w_price += $this->cellPadding; $w_priceall += $this->cellPadding; $w_cap = 210 - $this->borderLeft - $this->borderRight - $w_num - $w_vat - $w_price - $w_priceall; // Positionen $this->_mySetFont(true); $this->Cell($w_num, $this->cellHeight, CC_RESSOURCE_BASKETQUANTITY, 0, 0, 'L', 1); $this->Cell($w_cap, $this->cellHeight, CC_RESSOURCE_BASKETCAPTION, 0, 0, 'L'); $this->Cell($w_vat, $this->cellHeight, CC_RESSOURCE_BASKETVAT, 0, 0, 'L', 1); $this->Cell($w_price, $this->cellHeight, CC_RESSOURCE_BASKETPRICEONE, 0, 0, 'R'); $this->Cell($w_priceall, $this->cellHeight, CC_RESSOURCE_BASKETPRICEALL, 0, 1, 'R', 1); $this->_mySetFont(false); $this->Ln(2); $this->SetDrawColor(150, 150, 150); $this->Line($this->borderLeft, $this->GetY(), 210 - $this->borderRight, $this->GetY()); $this->Ln(2.5); foreach($this->order->items as $item) { // Anzahl Zeilen für Caption berechnen $caption = $item->caption . (CC_SITE_SHOWID && $item->id ? " [$item->id]" : ''); $lines = 1; $wordQueue = ''; foreach (explode(' ', $caption) as $word) { if ($this->getStringWidth($wordQueue . ' ' . $word) > $w_cap) { $lines++; $wordQueue = $word; } else $wordQueue .= ' ' . $word; } // Versuch ob Zeilen auf Seite passen $y2 = $this->GetY(); for ($i = 1; $i <= $lines; $i++) { $this->Cell(0, $this->cellHeight * $i, '', 0, 1); if ($this->GetY() < $y2) { $y2 = $this->GetY(); break; } else { $this->SetY($y2); } } $this->MultiCell($w_num, $this->cellHeight, format::quantity($item->quantity, $item->qprecision) . ' ' . $item->unit, 0, 'L'); $y = max($y2, $this->GetY()); $this->SetXY($this->col1x + $w_num, $y2); $this->MultiCell($w_cap, $this->cellHeight, $caption, 0, 'L', 1); $y = max($y, $this->GetY()); $this->SetXY($this->col1x + $w_num + $w_cap, $y2); $this->MultiCell($w_vat, $this->cellHeight, format::vat($item->vat), 0, 'R'); $y = max($y, $this->GetY()); $this->SetXY($this->col1x + $w_num + $w_cap + $w_vat, $y2); $this->MultiCell($w_price, $this->cellHeight, format::price($item->price, $this->order->currency), 0, 'R', 1); $y = max($y, $this->GetY()); $this->SetXY($this->col1x + $w_num + $w_cap + $w_vat + $w_price, $y2); $this->MultiCell($w_priceall, $this->cellHeight, format::price($item->price * $item->quantity, $this->order->currency), 0, 'R'); $y = max($y, $this->GetY()); $this->SetY($y); } $this->Ln(2); $this->Line($this->borderLeft, $this->GetY(), 210 - $this->borderRight, $this->GetY()); $this->SetDrawColor(0, 0, 0); $this->Ln(2.5); /////////////////////////////////////////////////////////////// // Aggregationsblock (nur letzte Seite Seite) // Zwischensummer $w = $w_num + $w_cap + $w_vat + $w_price; $this->Cell($w, $this->cellHeight, CC_RESSOURCE_BASKETSUBTOTAL . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_subtotal(), $this->order->currency), 0, 1, 'R'); // Rabatte if ($this->order->get_rebate()) { $this->Cell($w, $this->cellHeight, CC_RESSOURCE_REBATE . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_rebate(), $this->order->currency), 0, 1, 'R'); } // Versandkosten $this->Cell($w, $this->cellHeight, CC_RESSOURCE_SHIPPINGCOST . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_shipping_cost(), $this->order->currency), 0, 1, 'R'); // Bezahlkosten if (floatval($this->order->get_payment_cost())) { $this->Cell($w, $this->cellHeight, CC_RESSOURCE_PAYMENTCOST . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_payment_cost(), $this->order->currency), 0, 1, 'R'); } // Gesamtpreis $this->_mySetFont(true); if (CC_SITE_B2B) $this->Cell($w, $this->cellHeight, CC_RESSOURCE_BASKETNET . ':', 0, 0, 'R'); else $this->Cell($w, $this->cellHeight,CC_RESSOURCE_BASKETTOTAL . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_subtotal() - $this->order->get_rebate() + $this->order->get_shipping_cost() + $this->order->get_payment_cost(), $this->order->currency), 0, 1, 'R'); $this->_mySetFont(false); $this->Ln(); // Mehrwertsteuer if (!CC_SITE_B2B) $this->Cell(0, $this->cellHeight, CC_RESSOURCE_PRICEGROSS . ':', 0, 1, 'R'); if ($this->order->client->novat) $this->Cell(0, $this->cellHeight, CC_RESSOURCE_BASKETNOVAT, 0, 1, 'R'); else foreach ($this->order->vatarray->vatarray as $vat) { $this->Cell($w, $this->cellHeight, format::vat($vat->percent) . ' ' . CC_RESSOURCE_BASKETVAT . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($vat->amount, $this->order->currency), 0, 1, 'R'); } // Endpreis B2B if (CC_SITE_B2B) { $this->_mySetFont(true); $this->Cell($w, $this->cellHeight, CC_RESSOURCE_BASKETGROSS . ':', 0, 0, 'R'); $this->Cell(0, $this->cellHeight, format::price($this->order->get_subtotal() - $this->order->get_rebate() + $this->order->get_shipping_cost() + $this->order->get_payment_cost() + $this->order->get_totalvat(), $this->order->currency), 0, 1, 'R'); $this->_mySetFont(false); } // Sontiges if ($this->order->get_weight()) $this->Cell(0, $this->cellHeight, CC_RESSOURCE_BASKETTOTALWEIGHT . ': ' . format::weight($this->order->get_weight()), 0, 1, 'L'); $this->Cell(0, $this->cellHeight, CC_RESSOURCE_BASKETSELECTEDSHIPPING . ': ' . $this->order->sm->caption, 0, 1, 'L'); $this->Cell(0, $this->cellHeight, CC_RESSOURCE_BASKETSELECTEDPAYMENT . ': ' . $this->order->pm->caption, 0, 1, 'L'); if ($this->order->coupon_id) $this->Cell(0, $this->cellHeight, CC_RESSOURCE_COUPONCODE . ': ' . $this->order->coupon_id, 0, 1, 'L'); $this->Ln(); /////////////////////////////////////////////////////////////// // Informationsblock (nur letzte Seite) // Infotexte zur Bestellung if (CC_SITE_PDF_INFO) { $this->MultiCell(0, $this->cellHeight, str_replace('
', "\n", CC_SITE_PDF_INFO), 0, 'J'); $this->Ln(); } if (CC_SITE_PDF_ATTACHTERMS) { $this->MultiCell(0, $this->cellHeight, str_replace('
', "\n", CC_SITE_INFOTEXT), 0, 'J'); $this->Ln(); } $this->Output($this->filename(), 'F'); } // Gibt den Kopfbereich aus function Header() { /////////////////////////////////////////////////////////////// // Kopfbereich (jede Seite) automatisch Header() // Opt. Slogan $this->_mySetFontSlogan(); $this->Cell(0, $this->cellHeight, CC_SITE_PDF_HEAD_SLOGAN ? CC_SITE_PDF_HEAD_SLOGAN : ' ', 0, 1, 'L'); $this->_mySetFont(null); $this->Ln(); // Opt. Shoplogo if (CC_SITE_PDF_HEAD_LOGO) { $size = getimagesize(CC_SITE_PDF_HEAD_LOGO); $this->Image(CC_SITE_PDF_HEAD_LOGO, 210 - $this->borderRight - $this->size[0] * $this->logoHeight / $this->size[1], $this->borderTop, 0, $this->logoHeight); $this->SetY($this->borderTop + $this->logoHeight + 2); } if (CC_SITE_PDF_HEAD_SLOGAN || CC_SITE_PDF_HEAD_LOGO) { $this->Line($this->lineLeftX, $this->GetY(), $this->lineRightX, $this->GetY()); $this->Ln(); } $this->_mySetFont($this->bold); } // Gibt den Fußbereich aus function Footer() { $this->_mySetFont(null); /////////////////////////////////////////////////////////////// // Fußblock (jede Seite) automatisch Footer() $this->SetY(297 - $this->footerHeight); if (CC_SITE_PDF_FOOTER) { $this->Ln(); $this->Line($this->lineLeftX, $this->GetY(), $this->lineRightX, $this->GetY()); $this->Ln(); $this->MultiCell(0, $this->cellHeight, str_replace('
', "\n", CC_SITE_PDF_FOOTER), 0, 'C'); } /////////////////////////////////////////////////////////////// // Sequenzblock (jede Seite) automatisch Footer() // Seite $this->Ln(); $this->Cell(0, $this->cellHeight, CC_RESSOURCE_PAGE . ' ' . $this->PageNo(), 0, 0, 'R'); } } ?>