id) { $invoice_number = $this->invoice_number; $invoice_date = $this->invoice_date; } else { $invoice_number = "PROFORMA"; $invoice_date = 1; } $filename = ""; $positions = $this->getProperty("positions"); $vat = []; foreach ($positions as $p) { if (!array_key_exists($p->vatrate, $vat)) { $vat[$p->vatrate] = 0; } $vat[$p->vatrate] += $p->price_gross - ($p->price * $p->amount); } $pdf_vars = [ "invoice" => $this, "vat" => $vat, "bank_iban" => TT_INVOICE_BANK_IBAN, "bank_bic" => TT_INVOICE_BANK_BIC, "bank_bank"=> TT_INVOICE_BANK_BANK, "bank_owner" => TT_INVOICE_BANK_OWNER ]; // Replace placeholders in header $headerHtml = file_get_contents(BASEDIR . "/Layout/default/Invoice/PDF_HEADER.html"); $headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml); $headerHtml = str_replace("{{ addressLine_1 }}", $this->company ? $this->company : "", $headerHtml); $headerHtml = str_replace("{{ addressLine_2 }}", $this->firstname . " " . $this->lastname, $headerHtml); $headerHtml = str_replace("{{ addressLine_3 }}", nl2br($this->street), $headerHtml); $headerHtml = str_replace("{{ addressLine_4 }}", $this->zip . " " . $this->city, $headerHtml); $headerHtml = str_replace("{{ addressLine_5 }}", $this->country != "Österreich" ? $this->country : "", $headerHtml); $headerHtml = str_replace("{{ customerNumber }}", $this->customer_number, $headerHtml); $headerHtml = str_replace("{{ billingAccount }}", $this->fibu_account_number, $headerHtml); $headerHtml = str_replace("{{ invoiceNumber }}", $invoice_number, $headerHtml); $headerHtml = str_replace("{{ invoiceDate }}", date("d.m.Y", $invoice_date), $headerHtml); $headerHtml = str_replace("{{ vatHtml }}", $this->uid ? "Ihre UID:" . $this->uid . "" : "", $headerHtml); $headerHtml = str_replace("{{ qrCodeSrc }}", $this->getSepaQRCode($invoice_number, round($this->total_gross, 2)), $headerHtml); $headerFile = BASEDIR . "/var/temp/invoice_header-" . date("U") . "-" . rand(1000, 9999) . ".html"; file_put_contents($headerFile, $headerHtml); // Replace placeholders in header $footerHtml = file_get_contents(BASEDIR . "/Layout/default/Invoice/PDF_FOOTER.html"); $footerHtml = str_replace("{{ bank_iban }}", TT_INVOICE_BANK_IBAN_FORMATTED, $footerHtml); $footerHtml = str_replace("{{ bank_bic }}", TT_INVOICE_BANK_BIC, $footerHtml); $footerHtml = str_replace("{{ bank_bank }}", TT_INVOICE_BANK_BANK, $footerHtml); $footerHtml = str_replace("{{ bank_owner }}", TT_INVOICE_BANK_OWNER, $footerHtml); $footerFile = BASEDIR . "/var/temp/invoice_footer-" . date("U") . "-" . rand(1000, 9999) . ".html"; file_put_contents($footerFile, $footerHtml); $pdf = new PdfForm("Invoice/PDF_MAIN", $pdf_vars); $wkhtmltopdfArgs = "--header-html $headerFile --footer-html $footerFile"; $filename = $pdf->render($wkhtmltopdfArgs); return $filename; } public function getSepaQRCode($paymentReference, $amount) { $xinonIBAN = TT_INVOICE_BANK_IBAN; $xinonBIC = TT_INVOICE_BANK_BIC; $xinonOwner = TT_INVOICE_BANK_OWNER; $epc = "BCD 001 1 SCT $xinonBIC $xinonOwner $xinonIBAN EUR$amount XINO $paymentReference XINON GmbH"; return (new QRCode)->render($epc); } public function sendByEmail($to_email = false) { if(!$this->id) return false; $pdf = $this->getProperty("pdf"); if(!$pdf || !$pdf->name) { return false; } $pdf_filename = $pdf->getFullPath(); if(!$pdf_filename || !file_exists($pdf_filename)) { return false; } $tpl = new Layout(); $tpl->setTemplate("Emailtemplates/invoice/invoice-email"); $pdf_vars = [ "invoice" => $this ]; foreach($pdf_vars as $name => $val) { $tpl->set($name, $val); } $body = $tpl->render(); $values = $tpl->getReturnedValue(); $subject = $values['subject']; $from = $values['from_email']; $from_name = $values['from_email_name']; if($to_email) { $to = $to_email; } else { $to = trim($this->email); } if(!$to) { $this->log->error(__METHOD__.": Invoice ".$this->invoice_number." missing email"); } if(!$subject || !$from || !$from_name || !$to) { $this->log->warn(__METHOD__.": Invoice ".$this->invoice_number." could not be sent. Values missing. (subject: '$subject', from: '$from_name', from_email: '$from', to: '$to')"); return false; } else { $email = new Emailnotification(); $email->setSubject($subject); $email->setBody($body); $email->setFrom($from, $from_name); $email->setTo($to); $email->setHeader("X-".MFAPPNAME."-Iid", $this->id); $email->addAttachment($pdf_filename, null, $pdf->filename, "application/pdf"); $email->send(); $this->log->info(__METHOD__.": Sending Invoice ".$this->invoice_number." to $to"); } return true; } public function getProperty($name) { if($this->$name == null) { if(!$this->id) { return null; } if($name == "positions") { $positions = InvoicepositionModel::search(["invoice_id" => $this->id]); $this->positions = $positions; return $this->positions; } if($name == "voicenumbers") { $voicenumbers = InvoiceVoicenumberModel::search(["invoice_id" => $this->id]); $this->voicenumbers = $voicenumbers; return $this->voicenumbers; } if($name == "pdf") { $ifile = InvoiceFileModel::getFirst(["invoice_id" => $this->id]); if(!$ifile) return null; $file = $ifile->file; if(!$file) return null; $this->pdf = $file; return $this->pdf; } if($name == "creator") { $this->creator = mfValuecache::singleton()->get("Worker-id-".$this->create_by); if($this->creator === null) { $this->creator = new User($this->create_by); if($this->creator->id) { mfValuecache::singleton()->set("Worker-id-".$this->create_by, $this->creator); } } return $this->creator; } if($name == "editor") { $this->editor = mfValuecache::singleton()->get("Worker-id-".$this->edit_by); if($this->editor === null) { $this->editor = new User($this->edit_by); if($this->editor->id) { mfValuecache::singleton()->set("Worker-id-".$this->edit_by, $this->editor); } } return $this->editor; } $classname = ucfirst($name); $idfield = $name."_id"; $this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield); if(!$this->$name) { $this->$name = new $classname($this->$idfield); } if($this->$name->id) { mfValuecache::singleton()->set("mfObjectmodel-$name-".$this->$name->id, $this->$name); return $this->$name; } else { return null; } } return $this->$name; } }