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');
}
}
?>